📄 objects.c
字号:
} else if( i_delay == 20 ) { msg_Err( p_this, "waited too long, cancelling destruction (id=%d,type=%d)", p_this->i_object_id, p_this->i_object_type ); return; } msleep( 100000 ); } /* Destroy the associated variables, starting from the end so that * no memmove calls have to be done. */ while( p_this->i_vars ) { var_Destroy( p_this, p_this->p_vars[p_this->i_vars - 1].psz_name ); } free( p_this->p_vars ); vlc_mutex_destroy( &p_this->var_lock ); if( p_this->psz_header ) free( p_this->psz_header ); if( p_this->i_object_type == VLC_OBJECT_ROOT ) { /* We are the root object ... no need to lock. */ free( p_this->p_libvlc->pp_objects ); p_this->p_libvlc->pp_objects = NULL; p_this->p_libvlc->i_objects--; vlc_mutex_destroy( &structure_lock ); } else { 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_this->p_libvlc->pp_objects, p_this->p_libvlc->i_objects ); REMOVE_ELEM( p_this->p_libvlc->pp_objects, p_this->p_libvlc->i_objects, i_index ); vlc_mutex_unlock( &structure_lock ); } vlc_mutex_destroy( &p_this->object_lock ); vlc_cond_destroy( &p_this->object_wait ); /* root is not dynamically allocated by vlc_object_create */ if( p_this->i_object_type != VLC_OBJECT_ROOT ) free( p_this );}/** * 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; vlc_mutex_lock( &structure_lock ); pp_objects = p_this->p_libvlc->pp_objects; /* Perform our dichotomy */ for( i_max = p_this->p_libvlc->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_vlc ) ) { 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_vlc ) ) { p_found = FindObject( VLC_OBJECT( p_this->p_vlc ), 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;}/** **************************************************************************** * 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 ){ 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 ){ 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 );}/** **************************************************************************** * 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; vlc_mutex_lock( &structure_lock ); /* Look for the objects */ switch( i_mode & 0x000f ) { case FIND_ANYWHERE: pp_current = p_this->p_libvlc->pp_objects; pp_end = pp_current + p_this->p_libvlc->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_this->p_libvlc->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; } vlc_mutex_unlock( &structure_lock ); return p_list;}/***************************************************************************** * DumpCommand: print the current vlc structure ***************************************************************************** * This function prints either an ASCII tree showing the connections between * vlc objects, and additional information such as their refcount, thread ID, * etc. (command "tree"), or the same data as a simple list (command "list"). *****************************************************************************/static int DumpCommand( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ if( *psz_cmd == 't' ) { char psz_foo[2 * MAX_DUMPSTRUCTURE_DEPTH + 1]; vlc_object_t *p_object; if( *newval.psz_string ) { p_object = vlc_object_get( p_this, atoi(newval.psz_string) ); if( !p_object ) { return VLC_ENOOBJ; } } else { p_object = p_this->p_vlc ? VLC_OBJECT(p_this->p_vlc) : p_this; } vlc_mutex_lock( &structure_lock ); psz_foo[0] = '|'; DumpStructure( p_object, 0, psz_foo ); vlc_mutex_unlock( &structure_lock ); if( *newval.psz_string ) { vlc_object_release( p_this ); } } else if( *psz_cmd == 'l' ) { vlc_object_t **pp_current, **pp_end; vlc_mutex_lock( &structure_lock ); pp_current = p_this->p_libvlc->pp_objects; pp_end = pp_current + p_this->p_libvlc->i_objects; for( ; pp_current < pp_end ; pp_current++ ) { if( (*pp_current)->b_attached ) { PrintObject( *pp_current, "" ); } else { printf( " o %.8i %s (not attached)\n", (*pp_current)->i_object_id,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -