📄 objects.c
字号:
#endif vlc_spin_lock( &internals->ref_spin ); assert( internals->i_refcount > 0 ); if( internals->i_refcount > 1 ) { /* 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 */ /* 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 object list * so that it cannot be encountered by vlc_object_get() */ vlc_internals (internals->next)->prev = internals->prev; vlc_internals (internals->prev)->next = internals->next; /* Detach from parent to protect against FIND_CHILDREN */ vlc_object_detach_unlocked (p_this); /* Detach from children to protect against FIND_PARENT */ for (int i = 0; i < internals->i_children; i++) internals->pp_children[i]->p_parent = NULL; } vlc_mutex_unlock( &structure_lock ); if( b_should_destroy ) { free( internals->pp_children ); internals->pp_children = NULL; internals->i_children = 0; vlc_object_destroy( p_this ); }}/** **************************************************************************** * 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 */ assert (!p_this->p_parent); p_this->p_parent = p_parent; /* Attach the child to its parent */ vlc_object_internals_t *priv = vlc_internals( p_parent ); INSERT_ELEM( priv->pp_children, priv->i_children, priv->i_children, p_this ); vlc_mutex_unlock( &structure_lock );}static void vlc_object_detach_unlocked (vlc_object_t *p_this){ vlc_assert_locked (&structure_lock); if (p_this->p_parent == NULL) return; vlc_object_internals_t *priv = vlc_internals( p_this->p_parent ); int i_index, i; /* Remove p_this's parent */ p_this->p_parent = NULL; /* Remove all of p_parent's children which are p_this */ for( i_index = priv->i_children ; i_index-- ; ) { if( priv->pp_children[i_index] == p_this ) { priv->i_children--; for( i = i_index ; i < priv->i_children ; i++ ) priv->pp_children[i] = priv->pp_children[i+1]; } } if( priv->i_children ) { priv->pp_children = (vlc_object_t **)realloc( priv->pp_children, priv->i_children * sizeof(vlc_object_t *) ); } else { /* Special case - don't realloc() to zero to avoid leaking */ free( priv->pp_children ); priv->pp_children = NULL; }}/** **************************************************************************** * 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" ); else vlc_object_detach_unlocked( 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; int i_count = 0; /* Look for the objects */ switch( i_mode & 0x000f ) { case FIND_ANYWHERE: /* Modules should probably not be object, and the module should perhaps * not be shared across LibVLC instances. In the mean time, this ugly * hack is brought to you by Courmisch. */ if (i_type == VLC_OBJECT_MODULE) return vlc_list_find ((vlc_object_t *)vlc_global ()->p_module_bank, i_type, FIND_CHILD); return vlc_list_find (p_this->p_libvlc, i_type, FIND_CHILD); case FIND_CHILD: vlc_mutex_lock( &structure_lock ); i_count = CountChildren( p_this, i_type ); p_list = NewList( i_count ); /* Check allocation was successful */ if( p_list->i_count != i_count ) { vlc_mutex_unlock( &structure_lock ); 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 ); vlc_mutex_unlock( &structure_lock ); break; default: msg_Err( p_this, "unimplemented!" ); p_list = NewList( 0 ); break; } return p_list;}/** * Gets the list of children of an objects, and increment their reference * count. * @return a list (possibly empty) or NULL in case of error. */vlc_list_t *__vlc_list_children( vlc_object_t *obj ){ vlc_list_t *l; vlc_object_internals_t *priv = vlc_internals( obj ); vlc_mutex_lock( &structure_lock ); l = NewList( priv->i_children ); for (int i = 0; i < l->i_count; i++) { vlc_object_yield( priv->pp_children[i] ); l->p_values[i].p_object = priv->pp_children[i]; } vlc_mutex_unlock( &structure_lock ); return l;}/***************************************************************************** * 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 ){ (void)oldval; (void)p_data; if( *psz_cmd == 'l' ) { vlc_object_t *root = VLC_OBJECT (vlc_global ()), *cur = root; vlc_mutex_lock( &structure_lock ); do { PrintObject (cur, ""); cur = vlc_internals (cur)->next; } while (cur != root); vlc_mutex_unlock( &structure_lock ); } else { vlc_object_t *p_object = NULL; if( *newval.psz_string ) { char *end; int i_id = strtol( newval.psz_string, &end, 0 ); if( end != newval.psz_string ) p_object = vlc_object_get( i_id ); else /* try using the object's name to find it */ p_object = vlc_object_find_name( p_this, newval.psz_string, FIND_ANYWHERE ); if( !p_object ) { return VLC_ENOOBJ; } } vlc_mutex_lock( &structure_lock ); if( *psz_cmd == 't' ) { char psz_foo[2 * MAX_DUMPSTRUCTURE_DEPTH + 1]; if( !p_object ) p_object = p_this->p_libvlc ? VLC_OBJECT(p_this->p_libvlc) : p_this; psz_foo[0] = '|'; DumpStructure( p_object, 0, psz_foo ); } else if( *psz_cmd == 'v' ) { int i; if( !p_object ) p_object = p_this->p_libvlc ? VLC_OBJECT(p_this->p_libvlc) : p_this; PrintObject( p_object, "" ); if( !vlc_internals( p_object )->i_vars ) printf( " `-o No variables\n" ); for( i = 0; i < vlc_internals( p_object )->i_vars; i++ ) { variable_t *p_var = vlc_internals( p_object )->p_vars + i; const char *psz_type = "unknown"; switch( p_var->i_type & VLC_VAR_TYPE ) {#define MYCASE( type, nice ) \ case VLC_VAR_ ## type: \ psz_type = nice; \ break; MYCASE( VOID, "void" ); MYCASE( BOOL, "bool" ); MYCASE( INTEGER, "integer" ); MYCASE( HOTKEY, "hotkey" ); MYCASE( STRING, "string" ); MYCASE( MODULE, "module" ); MYCASE( FILE, "file" ); MYCASE( DIRECTORY, "directory" ); MYCASE( VARIABLE, "variable" ); MYCASE( FLOAT, "float" ); MYCASE( TIME, "time" ); MYCASE( ADDRESS, "address" ); MYCASE( MUTEX, "mutex" ); MYCASE( LIST, "list" );#undef MYCASE } printf( " %c-o \"%s\" (%s", i + 1 == vlc_internals( p_object )->i_vars ? '`' : '|', p_var->psz_name, psz_type ); if( p_var->psz_text ) printf( ", %s", p_var->psz_text ); printf( ")" ); if( p_var->i_type & VLC_VAR_ISCOMMAND ) printf( ", command" ); if( p_var->i_entries ) printf( ", %d callbacks", p_var->i_entries ); switch( p_var->i_type & 0x00f0 ) { case VLC_VAR_VOID: case VLC_VAR_MUTEX: break; case VLC_VAR_BOOL: printf( ": %s", p_var->val.b_bool ? "true" : "false" ); break; case VLC_VAR_INTEGER: printf( ": %d", p_var->val.i_int ); break; case VLC_VAR_STRING: printf( ": \"%s\"", p_var->val.psz_string ); break; case VLC_VAR_FLOAT: printf( ": %f", p_var->val.f_float ); break; case VLC_VAR_TIME: printf( ": %"PRIi64, (int64_t)p_var->val.i_time ); break; case VLC_VAR_ADDRESS: printf( ": %p", p_var->val.p_address ); break; case VLC_VAR_LIST: printf( ": TODO" ); break; } printf( "\n" ); } } vlc_mutex_unlock( &structure_lock ); if( *newval.psz_string ) { vlc_object_release( p_object ); } } return VLC_SUCCESS;}/***************************************************************************** * vlc_list_release: free a list previously allocated by vlc_list_find ***************************************************************************** * This function decreases the refcount of all objects in the list and * frees the list. *****************************************************************************/void vlc_list_release( vlc_list_t *p_list ){ int i_index; for( i_index = 0; i_index < p_list->i_count; i_index++ ) { vlc_object_release( p_list->p_values[i_index].p_object ); } free( p_list->p_values ); free( p_list );}/***************************************************************************** * dump an object. (Debug function) *****************************************************************************/void __vlc_object_dump( vlc_object_t *p_this ){ vlc_mutex_lock( &structure_lock ); char psz_foo[2 * MAX_DUMPSTRUCTURE_DEPTH + 1]; psz_foo[0] = '|'; DumpStructure( p_this, 0, psz_foo ); vlc_mutex_unlock( &structure_lock );}/* Following functions are local */static vlc_object_t * FindObject( vlc_object_t *p_this, int i_type, int i_mode ){ int i; vlc_object_t *p_tmp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -