Commit 6accad54 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Use a proper condition variable for variable callback handling

parent a235278d
...@@ -150,6 +150,7 @@ typedef struct vlc_object_internals_t ...@@ -150,6 +150,7 @@ typedef struct vlc_object_internals_t
/* Object variables */ /* Object variables */
variable_t * p_vars; variable_t * p_vars;
vlc_mutex_t var_lock; vlc_mutex_t var_lock;
vlc_cond_t var_wait;
int i_vars; int i_vars;
/* Thread properties, if any */ /* Thread properties, if any */
......
...@@ -173,6 +173,7 @@ void *__vlc_custom_create( vlc_object_t *p_this, size_t i_size, ...@@ -173,6 +173,7 @@ void *__vlc_custom_create( vlc_object_t *p_this, size_t i_size,
vlc_mutex_init( &p_priv->lock ); vlc_mutex_init( &p_priv->lock );
vlc_cond_init( &p_priv->wait ); vlc_cond_init( &p_priv->wait );
vlc_mutex_init( &p_priv->var_lock ); vlc_mutex_init( &p_priv->var_lock );
vlc_cond_init( &p_priv->var_wait );
vlc_spin_init( &p_priv->spin ); vlc_spin_init( &p_priv->spin );
p_priv->pipes[0] = p_priv->pipes[1] = -1; p_priv->pipes[0] = p_priv->pipes[1] = -1;
...@@ -296,6 +297,7 @@ static void vlc_object_destroy( vlc_object_t *p_this ) ...@@ -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 ); vlc_mutex_destroy( &p_priv->var_lock );
free( p_this->psz_header ); free( p_this->psz_header );
......
...@@ -762,6 +762,7 @@ int var_SetChecked( vlc_object_t *p_this, const char *psz_name, ...@@ -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 = &p_priv->p_vars[i_var];
p_var->b_incallback = false; 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 ) ...@@ -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 = &p_priv->p_vars[i_var];
p_var->b_incallback = false; 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: ...@@ -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 * We do i_tries tries before giving up, just in case the variable is being
* modified and called from a callback. * modified and called from a callback.
*****************************************************************************/ *****************************************************************************/
static int GetUnused( vlc_object_t *p_this, const char *psz_name ) 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 ); vlc_object_internals_t *p_priv = vlc_internals( p_this );
while( true ) while( true )
{ {
int i_var;
i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name ); i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );
if( i_var < 0 ) if( i_var < 0 )
{ {
...@@ -1157,15 +1160,9 @@ static int GetUnused( vlc_object_t *p_this, const char *psz_name ) ...@@ -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 ) mutex_cleanup_push( &p_priv->var_lock );
{ vlc_cond_wait( &p_priv->var_wait, &p_priv->var_lock );
msg_Err( p_this, "caught in a callback deadlock? ('%s')", psz_name ); vlc_cleanup_pop( );
return VLC_ETIMEOUT;
}
vlc_mutex_unlock( &p_priv->var_lock );
msleep( THREAD_SLEEP );
vlc_mutex_lock( &p_priv->var_lock );
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment