+void __vlc_object_kill( vlc_object_t *p_this )
+{
+ vlc_mutex_lock( &p_this->object_lock );
+ p_this->b_die = VLC_TRUE;
+ vlc_mutex_unlock( &p_this->object_lock );
+}
+
+
+vlc_bool_t __vlc_object_dying_unlocked( vlc_object_t *p_this )
+{
+ vlc_assert_locked( &p_this->object_lock );
+ return p_this->b_die;
+}
+
+
+vlc_bool_t __vlc_object_dying( vlc_object_t *p_this )
+{
+ vlc_bool_t b;
+ vlc_mutex_lock( &p_this->object_lock );
+ b = __vlc_object_dying_unlocked( p_this );
+ vlc_mutex_unlock( &p_this->object_lock );
+ return b;
+}
+
+
+/**
+ * find an object given its ID
+ *
+ * This function looks for the object whose i_object_id field is i_id. We
+ * use a dichotomy so that lookups are in log2(n).
+ *****************************************************************************/
+void * __vlc_object_get( vlc_object_t *p_this, int i_id )
+{
+ int i_max, i_middle;
+ vlc_object_t **pp_objects;
+ libvlc_global_data_t *p_libvlc_global = vlc_global();
+
+ vlc_mutex_lock( &structure_lock );
+
+ pp_objects = p_libvlc_global->pp_objects;
+
+ /* Perform our dichotomy */
+ for( i_max = p_libvlc_global->i_objects - 1 ; ; )
+ {
+ i_middle = i_max / 2;
+
+ if( pp_objects[i_middle]->i_object_id > i_id )
+ {
+ i_max = i_middle;
+ }
+ else if( pp_objects[i_middle]->i_object_id < i_id )
+ {
+ if( i_middle )
+ {
+ pp_objects += i_middle;
+ i_max -= i_middle;
+ }
+ else
+ {
+ /* This happens when there are only two remaining objects */
+ if( pp_objects[i_middle+1]->i_object_id == i_id )
+ {
+ vlc_mutex_unlock( &structure_lock );
+ pp_objects[i_middle+1]->i_refcount++;
+ return pp_objects[i_middle+1];
+ }
+ break;
+ }
+ }
+ else
+ {
+ vlc_mutex_unlock( &structure_lock );
+ pp_objects[i_middle]->i_refcount++;
+ return pp_objects[i_middle];
+ }
+
+ if( i_max == 0 )
+ {
+ /* this means that i_max == i_middle, and since we have already
+ * tested pp_objects[i_middle]), p_found is properly set. */
+ break;
+ }
+ }
+
+ vlc_mutex_unlock( &structure_lock );
+ return NULL;
+}
+
+/**
+ ****************************************************************************
+ * find a typed object and increment its refcount
+ *****************************************************************************
+ * This function recursively looks for a given object type. i_mode can be one
+ * of FIND_PARENT, FIND_CHILD or FIND_ANYWHERE.
+ *****************************************************************************/
+void * __vlc_object_find( vlc_object_t *p_this, int i_type, int i_mode )
+{
+ vlc_object_t *p_found;
+
+ vlc_mutex_lock( &structure_lock );
+
+ /* If we are of the requested type ourselves, don't look further */
+ if( !(i_mode & FIND_STRICT) && p_this->i_object_type == i_type )
+ {
+ p_this->i_refcount++;
+ vlc_mutex_unlock( &structure_lock );
+ return p_this;
+ }
+
+ /* Otherwise, recursively look for the object */
+ if( (i_mode & 0x000f) == FIND_ANYWHERE )
+ {
+ vlc_object_t *p_root = p_this;
+
+ /* Find the root */
+ while( p_root->p_parent != NULL &&
+ p_root != VLC_OBJECT( p_this->p_libvlc ) )
+ {
+ p_root = p_root->p_parent;
+ }
+
+ p_found = FindObject( p_root, i_type, (i_mode & ~0x000f)|FIND_CHILD );
+ if( p_found == NULL && p_root != VLC_OBJECT( p_this->p_libvlc ) )
+ {
+ p_found = FindObject( VLC_OBJECT( p_this->p_libvlc ),
+ i_type, (i_mode & ~0x000f)|FIND_CHILD );
+ }
+ }
+ else
+ {
+ p_found = FindObject( p_this, i_type, i_mode );
+ }
+
+ vlc_mutex_unlock( &structure_lock );
+
+ return p_found;
+}
+
+/**
+ ****************************************************************************
+ * find a named object and increment its refcount
+ *****************************************************************************
+ * This function recursively looks for a given object name. i_mode can be one
+ * of FIND_PARENT, FIND_CHILD or FIND_ANYWHERE.
+ *****************************************************************************/
+void * __vlc_object_find_name( vlc_object_t *p_this, const char *psz_name,
+ int i_mode )
+{
+ vlc_object_t *p_found;
+
+ vlc_mutex_lock( &structure_lock );
+
+ /* If have the requested name ourselves, don't look further */
+ if( !(i_mode & FIND_STRICT)
+ && p_this->psz_object_name
+ && !strcmp( p_this->psz_object_name, psz_name ) )
+ {
+ p_this->i_refcount++;
+ vlc_mutex_unlock( &structure_lock );
+ return p_this;
+ }
+
+ /* Otherwise, recursively look for the object */
+ if( (i_mode & 0x000f) == FIND_ANYWHERE )
+ {
+ vlc_object_t *p_root = p_this;
+
+ /* Find the root */
+ while( p_root->p_parent != NULL &&
+ p_root != VLC_OBJECT( p_this->p_libvlc ) )
+ {
+ p_root = p_root->p_parent;
+ }
+
+ p_found = FindObjectName( p_root, psz_name,
+ (i_mode & ~0x000f)|FIND_CHILD );
+ if( p_found == NULL && p_root != VLC_OBJECT( p_this->p_libvlc ) )
+ {
+ p_found = FindObjectName( VLC_OBJECT( p_this->p_libvlc ),
+ psz_name, (i_mode & ~0x000f)|FIND_CHILD );
+ }
+ }
+ else
+ {
+ p_found = FindObjectName( p_this, psz_name, i_mode );
+ }
+
+ vlc_mutex_unlock( &structure_lock );
+
+ return p_found;
+}
+
+/**
+ ****************************************************************************
+ * increment an object refcount
+ *****************************************************************************/
+void __vlc_object_yield( vlc_object_t *p_this )
+{
+ vlc_mutex_lock( &structure_lock );
+ p_this->i_refcount++;
+ vlc_mutex_unlock( &structure_lock );
+}
+
+/**
+ ****************************************************************************
+ * decrement an object refcount
+ *****************************************************************************/
+void __vlc_object_release( vlc_object_t *p_this )
+{
+ vlc_mutex_lock( &structure_lock );
+ p_this->i_refcount--;
+ vlc_mutex_unlock( &structure_lock );
+}
+
+/**
+ ****************************************************************************
+ * attach object to a parent object
+ *****************************************************************************
+ * This function sets p_this as a child of p_parent, and p_parent as a parent
+ * of p_this. This link can be undone using vlc_object_detach.
+ *****************************************************************************/
+void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent )
+{
+ if( !p_this ) return;
+
+ vlc_mutex_lock( &structure_lock );
+
+ /* Attach the parent to its child */
+ p_this->p_parent = p_parent;
+
+ /* Attach the child to its parent */
+ INSERT_ELEM( p_parent->pp_children, p_parent->i_children,
+ p_parent->i_children, p_this );
+
+ /* Climb up the tree to see whether we are connected with the root */
+ if( p_parent->b_attached )
+ {
+ SetAttachment( p_this, VLC_TRUE );
+ }
+
+ vlc_mutex_unlock( &structure_lock );
+}
+
+/**
+ ****************************************************************************
+ * detach object from its parent
+ *****************************************************************************
+ * This function removes all links between an object and its parent.
+ *****************************************************************************/
+void __vlc_object_detach( vlc_object_t *p_this )
+{
+ if( !p_this ) return;
+
+ vlc_mutex_lock( &structure_lock );
+ if( !p_this->p_parent )
+ {
+ msg_Err( p_this, "object is not attached" );
+ vlc_mutex_unlock( &structure_lock );
+ return;
+ }
+
+ /* Climb up the tree to see whether we are connected with the root */
+ if( p_this->p_parent->b_attached )
+ {
+ SetAttachment( p_this, VLC_FALSE );
+ }
+
+ DetachObject( p_this );
+ vlc_mutex_unlock( &structure_lock );
+ p_this = NULL;
+}
+
+/**
+ ****************************************************************************
+ * find a list typed objects and increment their refcount
+ *****************************************************************************
+ * This function recursively looks for a given object type. i_mode can be one
+ * of FIND_PARENT, FIND_CHILD or FIND_ANYWHERE.
+ *****************************************************************************/
+vlc_list_t * __vlc_list_find( vlc_object_t *p_this, int i_type, int i_mode )
+{
+ vlc_list_t *p_list;
+ vlc_object_t **pp_current, **pp_end;
+ int i_count = 0, i_index = 0;
+ libvlc_global_data_t *p_libvlc_global = vlc_global();
+
+ vlc_mutex_lock( &structure_lock );
+
+ /* Look for the objects */
+ switch( i_mode & 0x000f )
+ {
+ case FIND_ANYWHERE:
+ pp_current = p_libvlc_global->pp_objects;
+ pp_end = pp_current + p_libvlc_global->i_objects;
+
+ for( ; pp_current < pp_end ; pp_current++ )
+ {
+ if( (*pp_current)->b_attached
+ && (*pp_current)->i_object_type == i_type )
+ {
+ i_count++;
+ }
+ }
+
+ p_list = NewList( i_count );
+ pp_current = p_libvlc_global->pp_objects;
+
+ for( ; pp_current < pp_end ; pp_current++ )
+ {
+ if( (*pp_current)->b_attached
+ && (*pp_current)->i_object_type == i_type )
+ {
+ ListReplace( p_list, *pp_current, i_index );
+ if( i_index < i_count ) i_index++;
+ }
+ }
+ break;
+
+ case FIND_CHILD:
+ i_count = CountChildren( p_this, i_type );
+ p_list = NewList( i_count );
+
+ /* Check allocation was successful */
+ if( p_list->i_count != i_count )
+ {
+ msg_Err( p_this, "list allocation failed!" );
+ p_list->i_count = 0;
+ break;
+ }
+
+ p_list->i_count = 0;
+ ListChildren( p_list, p_this, i_type );
+ break;
+
+ default:
+ msg_Err( p_this, "unimplemented!" );
+ p_list = NewList( 0 );
+ break;
+ }