Commit 523ef308 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont
Browse files

The totally dumb reference checker

parent 1746fdda
......@@ -46,6 +46,11 @@ void system_End ( libvlc_int_t * );
int vlc_threads_init( void );
void vlc_threads_end( void );
vlc_object_t *vlc_threadobj (void);
#ifndef NDEBUG
void vlc_refcheck (vlc_object_t *obj);
#else
# define vlc_refcheck( obj ) (void)0
#endif
/*
* CPU capabilities
......
......@@ -1469,3 +1469,58 @@ static void ListChildren( vlc_list_t *p_list, vlc_object_t *p_this, int i_type )
ListChildren( p_list, p_tmp, i_type );
}
}
#ifndef NDEBUG
void vlc_refcheck (vlc_object_t *obj)
{
static unsigned errors = 0;
vlc_object_t *caller = vlc_threadobj ();
vlc_object_internals_t *priv = vlc_internals (obj);
int refs;
if (errors > 100)
return;
if (!caller)
return; /* main thread, not sure how to handle it */
/* An object can always access itself without reference! */
if (caller == obj)
return;
/* The calling thread is younger than the object.
* Access could be valid, we would need more accounting. */
if (caller->i_object_id > obj->i_object_id)
return;
vlc_spin_lock (&priv->ref_spin);
refs = priv->i_refcount;
vlc_spin_unlock (&priv->ref_spin);
/* Object has more than one reference.
* The current thread could be holding a valid reference. */
if (refs > 1)
return;
/* The parent of an object normally holds the unique reference.
* As not all objects are threads, it could also be an ancestor. */
vlc_mutex_lock (&structure_lock);
for (vlc_object_t *cur = obj; cur != NULL; cur = cur->p_parent)
if (cur == caller)
{
vlc_mutex_unlock (&structure_lock);
return;
}
vlc_mutex_unlock (&structure_lock);
#if 1
if (caller->i_object_type == VLC_OBJECT_PLAYLIST)
return; /* Playlist is too clever, or hopelessly broken. */
#endif
msg_Err (caller, "This thread is accessing...");
msg_Err (obj, "...this object in a suspicious manner.");
if (++errors == 100)
msg_Err (caller, "Too many reference errors");
}
#endif
......@@ -168,6 +168,7 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type )
static vlc_list_t dummy_null_list = {0, NULL, NULL};
vlc_object_internals_t *p_priv = vlc_internals( p_this );
vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
/* FIXME: if the variable already exists, we don't duplicate it. But we
......@@ -331,6 +332,7 @@ int __var_Destroy( vlc_object_t *p_this, const char *psz_name )
variable_t *p_var;
vlc_object_internals_t *p_priv = vlc_internals( p_this );
vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
i_var = GetUnused( p_this, psz_name );
......@@ -407,6 +409,7 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
vlc_value_t oldval;
vlc_object_internals_t *p_priv = vlc_internals( p_this );
vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );
......@@ -759,6 +762,7 @@ int __var_Set( vlc_object_t *p_this, const char *psz_name, vlc_value_t val )
vlc_value_t oldval;
vlc_object_internals_t *p_priv = vlc_internals( p_this );
vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
i_var = GetUnused( p_this, psz_name );
......@@ -836,6 +840,7 @@ int __var_Get( vlc_object_t *p_this, const char *psz_name, vlc_value_t *p_val )
variable_t *p_var;
vlc_object_internals_t *p_priv = vlc_internals( p_this );
vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );
......@@ -902,6 +907,7 @@ int __var_AddCallback( vlc_object_t *p_this, const char *psz_name,
callback_entry_t entry;
vlc_object_internals_t *p_priv = vlc_internals( p_this );
vlc_refcheck( p_this );
entry.pf_callback = pf_callback;
entry.p_data = p_data;
......@@ -939,6 +945,7 @@ int __var_DelCallback( vlc_object_t *p_this, const char *psz_name,
variable_t *p_var;
vlc_object_internals_t *p_priv = vlc_internals( p_this );
vlc_refcheck( p_this );
vlc_mutex_lock( &p_priv->var_lock );
i_var = GetUnused( p_this, psz_name );
......@@ -1575,6 +1582,7 @@ int __var_Command( vlc_object_t *p_this, const char *psz_name,
return VLC_ENOOBJ;
}
vlc_refcheck( p_this );
i_type = var_Type( p_obj, psz_cmd );
if( !( i_type&VLC_VAR_ISCOMMAND ) )
{
......
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