📄 objects.c
字号:
/***************************************************************************** * objects.c: vlc_object_t handling ***************************************************************************** * Copyright (C) 2004 VideoLAN * $Id: objects.c 10705 2005-04-16 12:24:32Z courmisch $ * * Authors: Samuel Hocevar <sam@zoy.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//** * \file * This file contains the functions to handle the vlc_object_t type *//***************************************************************************** * Preamble *****************************************************************************/#include <vlc/vlc.h>#include <vlc/input.h>#ifdef HAVE_STDLIB_H# include <stdlib.h> /* realloc() */#endif#include "vlc_video.h"#include "video_output.h"#include "vlc_spu.h"#include "audio_output.h"#include "aout_internal.h"#include "stream_output.h"#include "vlc_playlist.h"#include "vlc_interface.h"#include "vlc_codec.h"#include "vlc_filter.h"#include "vlc_httpd.h"#include "vlc_vlm.h"#include "vlc_vod.h"#include "vlc_tls.h"#include "vlc_xml.h"/***************************************************************************** * Local prototypes *****************************************************************************/static int DumpCommand( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );static vlc_object_t * FindObject ( vlc_object_t *, int, int );static void DetachObject ( vlc_object_t * );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 *, vlc_bool_t );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 int CountChildren ( vlc_object_t *, int );static void ListChildren ( vlc_list_t *, vlc_object_t *, int );/***************************************************************************** * Local structure lock *****************************************************************************/static vlc_mutex_t structure_lock;/***************************************************************************** * vlc_object_create: initialize a vlc object ***************************************************************************** * This function allocates memory for a vlc object and initializes it. If * i_type is not a known value such as VLC_OBJECT_ROOT, VLC_OBJECT_VOUT and * so on, vlc_object_create will use its value for the object size. *****************************************************************************//** * Initialize a vlc object * * This function allocates memory for a vlc object and initializes it. If * i_type is not a known value such as VLC_OBJECT_ROOT, VLC_OBJECT_VOUT and * so on, vlc_object_create will use its value for the object size. */void * __vlc_object_create( vlc_object_t *p_this, int i_type ){ vlc_object_t * p_new; char * psz_type; size_t i_size; switch( i_type ) { case VLC_OBJECT_ROOT: i_size = sizeof(libvlc_t); psz_type = "root"; break; case VLC_OBJECT_VLC: i_size = sizeof(vlc_t); psz_type = "vlc"; break; case VLC_OBJECT_MODULE: i_size = sizeof(module_t); psz_type = "module"; break; case VLC_OBJECT_INTF: i_size = sizeof(intf_thread_t); psz_type = "interface"; break; case VLC_OBJECT_DIALOGS: i_size = sizeof(intf_thread_t); psz_type = "dialogs provider"; break; case VLC_OBJECT_PLAYLIST: i_size = sizeof(playlist_t); psz_type = "playlist"; break; case VLC_OBJECT_SD: i_size = sizeof(services_discovery_t); psz_type = "services discovery"; break; case VLC_OBJECT_INPUT: i_size = sizeof(input_thread_t); psz_type = "input"; break; case VLC_OBJECT_DEMUX: i_size = sizeof(demux_t); psz_type = "demux"; break; case VLC_OBJECT_STREAM: i_size = sizeof(stream_t); psz_type = "stream"; break; case VLC_OBJECT_ACCESS: i_size = sizeof(access_t); psz_type = "access"; break; case VLC_OBJECT_DECODER: i_size = sizeof(decoder_t); psz_type = "decoder"; break; case VLC_OBJECT_PACKETIZER: i_size = sizeof(decoder_t); psz_type = "packetizer"; break; case VLC_OBJECT_ENCODER: i_size = sizeof(encoder_t); psz_type = "encoder"; break; case VLC_OBJECT_FILTER: i_size = sizeof(filter_t); psz_type = "filter"; break; case VLC_OBJECT_VOUT: i_size = sizeof(vout_thread_t); psz_type = "video output"; break; case VLC_OBJECT_SPU: i_size = sizeof(spu_t); psz_type = "subpicture unit"; break; case VLC_OBJECT_AOUT: i_size = sizeof(aout_instance_t); psz_type = "audio output"; break; case VLC_OBJECT_SOUT: i_size = sizeof(sout_instance_t); psz_type = "stream output"; break; case VLC_OBJECT_HTTPD: i_size = sizeof( httpd_t ); psz_type = "http daemon"; break; case VLC_OBJECT_VLM: i_size = sizeof( vlm_t ); psz_type = "vlm dameon"; break; case VLC_OBJECT_VOD: i_size = sizeof( vod_t ); psz_type = "vod server"; break; case VLC_OBJECT_TLS: i_size = sizeof( tls_t ); psz_type = "tls"; break; case VLC_OBJECT_XML: i_size = sizeof( xml_t ); psz_type = "xml"; break; case VLC_OBJECT_OPENGL: i_size = sizeof( vout_thread_t ); psz_type = "opengl provider"; break; case VLC_OBJECT_ANNOUNCE: i_size = sizeof( announce_handler_t ); psz_type = "announce handler"; break; default: i_size = i_type > 0 ? i_type > (int)sizeof(vlc_object_t) ? i_type : (int)sizeof(vlc_object_t) : (int)sizeof(vlc_object_t); i_type = VLC_OBJECT_GENERIC; psz_type = "generic"; break; } if( i_type == VLC_OBJECT_ROOT ) { p_new = p_this; } else { p_new = malloc( i_size ); if( !p_new ) return NULL; memset( p_new, 0, i_size ); } p_new->i_object_type = i_type; p_new->psz_object_type = psz_type; p_new->psz_object_name = NULL; p_new->b_die = VLC_FALSE; p_new->b_error = VLC_FALSE; p_new->b_dead = VLC_FALSE; p_new->b_attached = VLC_FALSE; p_new->b_force = VLC_FALSE; p_new->i_vars = 0; p_new->p_vars = (variable_t *)malloc( 16 * sizeof( variable_t ) ); if( !p_new->p_vars ) { if( i_type != VLC_OBJECT_ROOT ) free( p_new ); return NULL; } if( i_type == VLC_OBJECT_ROOT ) { /* If i_type is root, then p_new is actually p_libvlc */ p_new->p_libvlc = (libvlc_t*)p_new; p_new->p_vlc = NULL; p_new->p_libvlc->i_counter = 0; p_new->i_object_id = 0; p_new->p_libvlc->i_objects = 1; p_new->p_libvlc->pp_objects = malloc( sizeof(vlc_object_t *) ); p_new->p_libvlc->pp_objects[0] = p_new; p_new->b_attached = VLC_TRUE; } else { p_new->p_libvlc = p_this->p_libvlc; p_new->p_vlc = ( i_type == VLC_OBJECT_VLC ) ? (vlc_t*)p_new : p_this->p_vlc; vlc_mutex_lock( &structure_lock ); p_new->p_libvlc->i_counter++; p_new->i_object_id = p_new->p_libvlc->i_counter; /* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's * useless to try and recover anything if pp_objects gets smashed. */ INSERT_ELEM( p_new->p_libvlc->pp_objects, p_new->p_libvlc->i_objects, p_new->p_libvlc->i_objects, p_new ); vlc_mutex_unlock( &structure_lock ); } p_new->i_refcount = 0; p_new->p_parent = NULL; p_new->pp_children = NULL; p_new->i_children = 0; p_new->p_private = NULL; /* Initialize mutexes and condvars */ vlc_mutex_init( p_new, &p_new->object_lock ); vlc_cond_init( p_new, &p_new->object_wait ); vlc_mutex_init( p_new, &p_new->var_lock ); if( i_type == VLC_OBJECT_ROOT ) { vlc_mutex_init( p_new, &structure_lock ); var_Create( p_new, "list", VLC_VAR_STRING | VLC_VAR_ISCOMMAND ); var_AddCallback( p_new, "list", DumpCommand, NULL ); var_Create( p_new, "tree", VLC_VAR_STRING | VLC_VAR_ISCOMMAND ); var_AddCallback( p_new, "tree", DumpCommand, NULL ); } return p_new;}/** **************************************************************************** * Destroy a vlc object * * This function destroys an object that has been previously allocated with * vlc_object_create. The object's refcount must be zero and it must not be * attached to other objects in any way. *****************************************************************************/void __vlc_object_destroy( vlc_object_t *p_this ){ int i_delay = 0; if( p_this->i_children ) { msg_Err( p_this, "cannot delete object (%i, %s) with children" , p_this->i_object_id, p_this->psz_object_name ); return; } if( p_this->p_parent ) { msg_Err( p_this, "cannot delete object (%i, %s) with a parent", p_this->i_object_id, p_this->psz_object_name ); return; } while( p_this->i_refcount ) { i_delay++; /* Don't warn immediately ... 100ms seems OK */ if( i_delay == 2 ) { msg_Warn( p_this, "refcount is %i, delaying before deletion", p_this->i_refcount ); } else if( i_delay == 12 ) { msg_Err( p_this, "refcount is %i, I have a bad feeling about this", p_this->i_refcount ); } else if( i_delay == 42 ) { msg_Err( p_this, "we waited too long, cancelling destruction" ); 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 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -