[vlc-devel] commit: Fix potential deadlock between ressource and interface. ( Laurent Aimar )

git version control git at videolan.org
Tue Jan 6 21:37:52 CET 2009


vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Tue Jan  6 19:56:22 2009 +0100| [29033fb8395ecf427ba917247a4ef197caf63de8] | committer: Laurent Aimar 

Fix potential deadlock between ressource and interface.

Without it, input_ressource_HoldVout and vout windows request could deadlock.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=29033fb8395ecf427ba917247a4ef197caf63de8
---

 src/input/ressource.c |   48 +++++++++++++++++++++++++++++++++++-------------
 1 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/src/input/ressource.c b/src/input/ressource.c
index a3ba994..d8131a0 100644
--- a/src/input/ressource.c
+++ b/src/input/ressource.c
@@ -41,17 +41,23 @@
 
 struct input_ressource_t
 {
+    /* This lock is used to serialize request and protect
+     * our variables */
     vlc_mutex_t    lock;
 
+    /* */
     input_thread_t *p_input;
 
     sout_instance_t *p_sout;
+    vout_thread_t   *p_vout_free;
+    aout_instance_t *p_aout;
 
+    /* This lock is used to protect vout ressources access (for hold)
+     * It is a special case because of embed video (possible deadlock
+     * between vout window request and vout holds in some(qt4) interface) */
+    vlc_mutex_t    lock_vout;
     int             i_vout;
     vout_thread_t   **pp_vout;
-    vout_thread_t   *p_vout_free;
-
-    aout_instance_t *p_aout;
 };
 
 /* */
@@ -192,7 +198,10 @@ static vout_thread_t *RequestVout( input_ressource_t *p_ressource,
         else if( p_vout )
         {
             assert( p_vout != p_ressource->p_vout_free );
+
+            vlc_mutex_lock( &p_ressource->lock_vout );
             TAB_REMOVE( p_ressource->i_vout, p_ressource->pp_vout, p_vout );
+            vlc_mutex_unlock( &p_ressource->lock_vout );
         }
 
         /* */
@@ -201,13 +210,21 @@ static vout_thread_t *RequestVout( input_ressource_t *p_ressource,
             return NULL;
 
         DisplayVoutTitle( p_ressource, p_vout );
+
+        vlc_mutex_lock( &p_ressource->lock_vout );
         TAB_APPEND( p_ressource->i_vout, p_ressource->pp_vout, p_vout );
+        vlc_mutex_unlock( &p_ressource->lock_vout );
+
         return p_vout;
     }
     else
     {
         assert( p_vout );
+
+        vlc_mutex_lock( &p_ressource->lock_vout );
         TAB_REMOVE( p_ressource->i_vout, p_ressource->pp_vout, p_vout );
+        vlc_mutex_unlock( &p_ressource->lock_vout );
+
         if( p_ressource->p_vout_free )
         {
             msg_Dbg( p_ressource->p_input, "detroying vout (already one saved)" );
@@ -228,10 +245,14 @@ static vout_thread_t *HoldVout( input_ressource_t *p_ressource )
         return NULL;
 
     /* TODO FIXME: p_ressource->pp_vout order is NOT stable */
+    vlc_mutex_lock( &p_ressource->lock_vout );
+
     vout_thread_t *p_vout = p_ressource->pp_vout[0];
 
     vlc_object_hold( p_vout );
 
+    vlc_mutex_unlock( &p_ressource->lock_vout );
+
     return p_vout;
 }
 static void HoldVouts( input_ressource_t *p_ressource, vout_thread_t ***ppp_vout, int *pi_vout )
@@ -240,12 +261,15 @@ static void HoldVouts( input_ressource_t *p_ressource, vout_thread_t ***ppp_vout
 
     *pi_vout = 0;
     *ppp_vout = NULL;
+
+    vlc_mutex_lock( &p_ressource->lock_vout );
+
     if( p_ressource->i_vout <= 0 )
-        return;
+        goto exit;
 
     pp_vout = calloc( p_ressource->i_vout, sizeof(*pp_vout) );
     if( !pp_vout )
-        return;
+        goto exit;
 
     *ppp_vout = pp_vout;
     *pi_vout = p_ressource->i_vout;
@@ -255,6 +279,9 @@ static void HoldVouts( input_ressource_t *p_ressource, vout_thread_t ***ppp_vout
         pp_vout[i] = p_ressource->pp_vout[i];
         vlc_object_hold( pp_vout[i] );
     }
+
+exit:
+    vlc_mutex_unlock( &p_ressource->lock_vout );
 }
 
 /* */
@@ -300,7 +327,6 @@ static aout_instance_t *HoldAout( input_ressource_t *p_ressource )
     if( !p_ressource->p_aout )
         return NULL;
 
-    /* TODO FIXME: p_ressource->pp_vout order is NOT stable */
     aout_instance_t *p_aout = p_ressource->p_aout;
 
     vlc_object_hold( p_aout );
@@ -315,6 +341,7 @@ input_ressource_t *input_ressource_New( void )
         return NULL;
 
     vlc_mutex_init( &p_ressource->lock );
+    vlc_mutex_init( &p_ressource->lock_vout );
     return p_ressource;
 }
 
@@ -324,6 +351,7 @@ void input_ressource_Delete( input_ressource_t *p_ressource )
     DestroyVout( p_ressource );
     DestroyAout( p_ressource );
 
+    vlc_mutex_destroy( &p_ressource->lock_vout );
     vlc_mutex_destroy( &p_ressource->lock );
     free( p_ressource );
 }
@@ -362,17 +390,11 @@ vout_thread_t *input_ressource_RequestVout( input_ressource_t *p_ressource,
 }
 vout_thread_t *input_ressource_HoldVout( input_ressource_t *p_ressource )
 {
-    vlc_mutex_lock( &p_ressource->lock );
-    vout_thread_t *p_ret = HoldVout( p_ressource );
-    vlc_mutex_unlock( &p_ressource->lock );
-
-    return p_ret;
+    return HoldVout( p_ressource );
 }
 void input_ressource_HoldVouts( input_ressource_t *p_ressource, vout_thread_t ***ppp_vout, int *pi_vout )
 {
-    vlc_mutex_lock( &p_ressource->lock );
     HoldVouts( p_ressource, ppp_vout, pi_vout );
-    vlc_mutex_unlock( &p_ressource->lock );
 }
 void input_ressource_TerminateVout( input_ressource_t *p_ressource )
 {




More information about the vlc-devel mailing list