Use a proper condition variable for variable callback handling
authorRémi Denis-Courmont <rdenis@simphalempin.com>
Mon, 5 Jan 2009 17:48:17 +0000 (19:48 +0200)
committerRémi Denis-Courmont <rdenis@simphalempin.com>
Mon, 5 Jan 2009 18:03:02 +0000 (20:03 +0200)
src/libvlc.h
src/misc/objects.c
src/misc/variables.c

index 5859ece..eadc1fa 100644 (file)
@@ -150,6 +150,7 @@ typedef struct vlc_object_internals_t
     /* Object variables */
     variable_t *    p_vars;
     vlc_mutex_t     var_lock;
     /* Object variables */
     variable_t *    p_vars;
     vlc_mutex_t     var_lock;
+    vlc_cond_t      var_wait;
     int             i_vars;
 
     /* Thread properties, if any */
     int             i_vars;
 
     /* Thread properties, if any */
index 5c53b20..070193d 100644 (file)
@@ -173,6 +173,7 @@ void *__vlc_custom_create( vlc_object_t *p_this, size_t i_size,
     vlc_mutex_init( &p_priv->lock );
     vlc_cond_init( &p_priv->wait );
     vlc_mutex_init( &p_priv->var_lock );
     vlc_mutex_init( &p_priv->lock );
     vlc_cond_init( &p_priv->wait );
     vlc_mutex_init( &p_priv->var_lock );
+    vlc_cond_init( &p_priv->var_wait );
     vlc_spin_init( &p_priv->spin );
     p_priv->pipes[0] = p_priv->pipes[1] = -1;
 
     vlc_spin_init( &p_priv->spin );
     p_priv->pipes[0] = p_priv->pipes[1] = -1;
 
@@ -296,6 +297,7 @@ static void vlc_object_destroy( vlc_object_t *p_this )
     }
 
     free( p_priv->p_vars );
     }
 
     free( p_priv->p_vars );
+    vlc_cond_destroy( &p_priv->var_wait );
     vlc_mutex_destroy( &p_priv->var_lock );
 
     free( p_this->psz_header );
     vlc_mutex_destroy( &p_priv->var_lock );
 
     free( p_this->psz_header );
index 0d647a6..dc0e8e6 100644 (file)
@@ -762,6 +762,7 @@ int var_SetChecked( vlc_object_t *p_this, const char *psz_name,
 
         p_var = &p_priv->p_vars[i_var];
         p_var->b_incallback = false;
 
         p_var = &p_priv->p_vars[i_var];
         p_var->b_incallback = false;
+        vlc_cond_broadcast( &p_priv->var_wait );
     }
 
     /* Free data if needed */
     }
 
     /* Free data if needed */
@@ -978,6 +979,7 @@ int __var_TriggerCallback( vlc_object_t *p_this, const char *psz_name )
 
         p_var = &p_priv->p_vars[i_var];
         p_var->b_incallback = false;
 
         p_var = &p_priv->p_vars[i_var];
         p_var->b_incallback = false;
+        vlc_cond_broadcast( &p_priv->var_wait );
     }
 
     vlc_mutex_unlock( &p_priv->var_lock );
     }
 
     vlc_mutex_unlock( &p_priv->var_lock );
@@ -1134,18 +1136,19 @@ cleanup:
 /* Following functions are local */
 
 /*****************************************************************************
 /* Following functions are local */
 
 /*****************************************************************************
- * GetUnused: find an unused variable from its name
+ * GetUnused: find an unused (not in callback) variable from its name
  *****************************************************************************
  * We do i_tries tries before giving up, just in case the variable is being
  * modified and called from a callback.
  *****************************************************************************/
 static int GetUnused( vlc_object_t *p_this, const char *psz_name )
 {
  *****************************************************************************
  * We do i_tries tries before giving up, just in case the variable is being
  * modified and called from a callback.
  *****************************************************************************/
 static int GetUnused( vlc_object_t *p_this, const char *psz_name )
 {
-    int i_var, i_tries = 0;
     vlc_object_internals_t *p_priv = vlc_internals( p_this );
 
     while( true )
     {
     vlc_object_internals_t *p_priv = vlc_internals( p_this );
 
     while( true )
     {
+        int i_var;
+
         i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );
         if( i_var < 0 )
         {
         i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );
         if( i_var < 0 )
         {
@@ -1157,15 +1160,9 @@ static int GetUnused( vlc_object_t *p_this, const char *psz_name )
             return i_var;
         }
 
             return i_var;
         }
 
-        if( i_tries++ > 100 )
-        {
-            msg_Err( p_this, "caught in a callback deadlock? ('%s')", psz_name );
-            return VLC_ETIMEOUT;
-        }
-
-        vlc_mutex_unlock( &p_priv->var_lock );
-        msleep( THREAD_SLEEP );
-        vlc_mutex_lock( &p_priv->var_lock );
+        mutex_cleanup_push( &p_priv->var_lock );
+        vlc_cond_wait( &p_priv->var_wait, &p_priv->var_lock );
+        vlc_cleanup_pop( );
     }
 }
 
     }
 }