static void PrintObject ( vlc_object_t *, const char * );
static void DumpStructure ( vlc_object_t *, int, char * );
static int FindIndex ( vlc_object_t *, vlc_object_t **, int );
-static void SetAttachment ( vlc_object_t *, bool );
static vlc_list_t * NewList ( int );
static void ListReplace ( vlc_list_t *, vlc_object_t *, int );
-static void ListAppend ( vlc_list_t *, vlc_object_t * );
+/*static void ListAppend ( vlc_list_t *, vlc_object_t * );*/
static int CountChildren ( vlc_object_t *, int );
static void ListChildren ( vlc_list_t *, vlc_object_t *, int );
void __vlc_object_release( vlc_object_t *p_this )
{
vlc_object_internals_t *internals = vlc_internals( p_this );
- bool b_should_destroy;
vlc_spin_lock( &internals->ref_spin );
assert( internals->i_refcount > 0 );
- if( internals->i_refcount > 1 )
+ if( --internals->i_refcount )
{
/* Fast path */
/* There are still other references to the object */
- internals->i_refcount--;
vlc_spin_unlock( &internals->ref_spin );
return;
}
vlc_spin_unlock( &internals->ref_spin );
- /* Slow path */
+ /* Slow path : object destruction */
/* Remember that we cannot hold the spin while waiting on the mutex */
vlc_mutex_lock( &structure_lock );
- /* Take the spin again. Note that another thread may have yielded the
- * object in the (very short) mean time. */
- vlc_spin_lock( &internals->ref_spin );
- b_should_destroy = --internals->i_refcount == 0;
- vlc_spin_unlock( &internals->ref_spin );
- if( b_should_destroy )
- {
- /* Remove the object from the table so that it cannot be returned from
- * vlc_object_find() and friends. */
- libvlc_global_data_t *p_libvlc_global = vlc_global();
- int i_index;
-
- 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 );
- if (p_this->p_parent)
- vlc_object_detach_unlocked (p_this);
- }
+ /* Remove the object from the table
+ * so that it cannot be encountered by vlc_object_get() */
+ libvlc_global_data_t *p_libvlc_global = vlc_global();
+ int i_index;
+
+ 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 );
+
+ /* Detach from parent to protect against FIND_CHILDREN */
+ if (p_this->p_parent)
+ vlc_object_detach_unlocked (p_this);
+ /* Detach from children to protect against FIND_PARENT */
+ for (int i = 0; i < p_this->i_children; i++)
+ p_this->pp_children[i]->p_parent = NULL;
vlc_mutex_unlock( &structure_lock );
- if( b_should_destroy )
- vlc_object_destroy( p_this );
+ vlc_object_destroy( p_this );
}
/**
vlc_mutex_lock( &structure_lock );
/* Attach the parent to its child */
+ assert (!p_this->p_parent);
p_this->p_parent = p_parent;
/* Attach the child to its parent */
}
-static void vlc_tree_find (vlc_object_t *node, int type, vlc_list_t *list)
-{
- assert (node);
- vlc_assert_locked (&structure_lock);
-
- if (node->i_object_type == type)
- ListAppend (list, node);
-
- for (int i = 0; i < node->i_children; i++)
- vlc_tree_find (node->pp_children[i], type, list);
-}
-
/**
****************************************************************************
* find a list typed objects and increment their refcount
vlc_list_t * __vlc_list_find( vlc_object_t *p_this, int i_type, int i_mode )
{
vlc_list_t *p_list;
- int i_count = 0, i_index = 0;
- libvlc_global_data_t *p_libvlc_global = vlc_global();
-
- vlc_mutex_lock( &structure_lock );
+ int i_count = 0;
/* Look for the objects */
switch( i_mode & 0x000f )
{
case FIND_ANYWHERE:
- p_list = NewList (0);
- if (p_list != NULL)
- vlc_tree_find (VLC_OBJECT (p_libvlc_global), i_type, p_list);
- break;
+ return vlc_list_find (vlc_global (), i_type, FIND_CHILD);
case FIND_CHILD:
+ vlc_mutex_lock( &structure_lock );
i_count = CountChildren( p_this, i_type );
p_list = NewList( i_count );
p_list->i_count = 0;
ListChildren( p_list, p_this, i_type );
+ vlc_mutex_unlock( &structure_lock );
break;
default:
break;
}
- vlc_mutex_unlock( &structure_lock );
-
return p_list;
}
return;
}
-static void ListAppend( vlc_list_t *p_list, vlc_object_t *p_object )
+/*static void ListAppend( vlc_list_t *p_list, vlc_object_t *p_object )
{
if( p_list == NULL )
{
p_list->i_count++;
return;
-}
+}*/
static int CountChildren( vlc_object_t *p_this, int i_type )
{