Commit 68aaf2c9 authored by Pierre d'Herbemont's avatar Pierre d'Herbemont

misc/objects.c: Make sure vlc_object_get won't return free-ed objects, by...

misc/objects.c: Make sure vlc_object_get won't return free-ed objects, by doing an atomic refcount decrease and object removal from the object list bank.
parent df291664
...@@ -75,6 +75,12 @@ ...@@ -75,6 +75,12 @@
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
typedef enum vlc_lock_state_t
{
vlc_Locked,
vlc_Unlocked
} vlc_lock_state_t;
static int DumpCommand( vlc_object_t *, char const *, static int DumpCommand( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * ); vlc_value_t, vlc_value_t, void * );
...@@ -93,6 +99,7 @@ static int CountChildren ( vlc_object_t *, int ); ...@@ -93,6 +99,7 @@ static int CountChildren ( vlc_object_t *, int );
static void ListChildren ( vlc_list_t *, vlc_object_t *, int ); static void ListChildren ( vlc_list_t *, vlc_object_t *, int );
static void vlc_object_destroy( vlc_object_t *p_this ); static void vlc_object_destroy( vlc_object_t *p_this );
static void vlc_object_release_locked( vlc_object_t *p_this, vlc_lock_state_t locked );
/***************************************************************************** /*****************************************************************************
* Local structure lock * Local structure lock
...@@ -365,6 +372,7 @@ static void vlc_object_destroy( vlc_object_t *p_this ) ...@@ -365,6 +372,7 @@ static void vlc_object_destroy( vlc_object_t *p_this )
if( (vlc_object_t *)p_this->p_libvlc == p_this ) if( (vlc_object_t *)p_this->p_libvlc == p_this )
logger = NULL; logger = NULL;
/* Sanity checks */
if( p_this->i_children ) if( p_this->i_children )
{ {
int i; int i;
...@@ -412,12 +420,6 @@ static void vlc_object_destroy( vlc_object_t *p_this ) ...@@ -412,12 +420,6 @@ static void vlc_object_destroy( vlc_object_t *p_this )
{ {
libvlc_global_data_t *p_global = (libvlc_global_data_t *)p_this; libvlc_global_data_t *p_global = (libvlc_global_data_t *)p_this;
/* Remove ourselves */
int i_index = FindIndex( p_this, p_global->pp_objects,
p_global->i_objects );
REMOVE_ELEM( p_global->pp_objects,
p_global->i_objects, i_index );
/* Test for leaks */ /* Test for leaks */
if( p_global->i_objects > 0 ) if( p_global->i_objects > 0 )
{ {
...@@ -442,22 +444,6 @@ static void vlc_object_destroy( vlc_object_t *p_this ) ...@@ -442,22 +444,6 @@ static void vlc_object_destroy( vlc_object_t *p_this )
vlc_mutex_destroy( &structure_lock ); vlc_mutex_destroy( &structure_lock );
} }
else
{
libvlc_global_data_t *p_libvlc_global = vlc_global();
int i_index;
vlc_mutex_lock( &structure_lock );
/* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's
* useless to try and recover anything if pp_objects gets smashed. */
i_index = FindIndex( p_this, p_libvlc_global->pp_objects,
p_libvlc_global->i_objects );
REMOVE_ELEM( p_libvlc_global->pp_objects,
p_libvlc_global->i_objects, i_index );
vlc_mutex_unlock( &structure_lock );
}
#if defined(WIN32) || defined(UNDER_CE) #if defined(WIN32) || defined(UNDER_CE)
/* if object has an associated thread, close it now */ /* if object has an associated thread, close it now */
...@@ -901,29 +887,37 @@ void __vlc_object_yield( vlc_object_t *p_this ) ...@@ -901,29 +887,37 @@ void __vlc_object_yield( vlc_object_t *p_this )
* And destroy the object if its refcount reach zero. * And destroy the object if its refcount reach zero.
*****************************************************************************/ *****************************************************************************/
void __vlc_object_release( vlc_object_t *p_this ) void __vlc_object_release( vlc_object_t *p_this )
{
vlc_object_release_locked( p_this, vlc_Unlocked );
}
/* Version without the lock */
static void vlc_object_release_locked( vlc_object_t *p_this, vlc_lock_state_t locked )
{ {
vlc_bool_t b_should_destroy; vlc_bool_t b_should_destroy;
vlc_mutex_lock( &structure_lock ); if(locked == vlc_Unlocked) vlc_mutex_lock( &structure_lock );
assert( p_this->p_internals->i_refcount > 0 ); assert( p_this->p_internals->i_refcount > 0 );
p_this->p_internals->i_refcount--; p_this->p_internals->i_refcount--;
b_should_destroy = (p_this->p_internals->i_refcount == 0); b_should_destroy = (p_this->p_internals->i_refcount == 0);
vlc_mutex_unlock( &structure_lock );
if( b_should_destroy ) if( b_should_destroy )
vlc_object_destroy( p_this ); {
} /* Make sure this object can't be obtained via vlc_find_object now that
* it is freed */
libvlc_global_data_t *p_libvlc_global = vlc_global();
int i_index;
/* Version without the lock */ /* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's
static void vlc_object_release_locked( vlc_object_t *p_this ) * useless to try and recover anything if pp_objects gets smashed. */
{ i_index = FindIndex( p_this, p_libvlc_global->pp_objects,
vlc_bool_t b_should_destroy; p_libvlc_global->i_objects );
REMOVE_ELEM( p_libvlc_global->pp_objects,
p_libvlc_global->i_objects, i_index );
}
assert( p_this->p_internals->i_refcount > 0 ); if(locked == vlc_Unlocked) vlc_mutex_unlock( &structure_lock );
p_this->p_internals->i_refcount--;
b_should_destroy = (p_this->p_internals->i_refcount == 0);
if( b_should_destroy ) if( b_should_destroy )
vlc_object_destroy( p_this ); vlc_object_destroy( p_this );
...@@ -1250,7 +1244,7 @@ void vlc_list_release( vlc_list_t *p_list ) ...@@ -1250,7 +1244,7 @@ void vlc_list_release( vlc_list_t *p_list )
vlc_mutex_lock( &structure_lock ); vlc_mutex_lock( &structure_lock );
for( i_index = 0; i_index < p_list->i_count; i_index++ ) for( i_index = 0; i_index < p_list->i_count; i_index++ )
{ {
vlc_object_release_locked( p_list->p_values[i_index].p_object ); vlc_object_release_locked( p_list->p_values[i_index].p_object, vlc_Locked );
} }
vlc_mutex_unlock( &structure_lock ); vlc_mutex_unlock( &structure_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