/*****************************************************************************
* objects.c: vlc_object_t handling
*****************************************************************************
- * Copyright (C) 2004-2007 the VideoLAN team
+ * Copyright (C) 2004-2008 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
#include "vlc_httpd.h"
#include "vlc_vlm.h"
#include "input/vlm_internal.h"
-#include "vlc_vod.h"
-#include "vlc_tls.h"
-#include "vlc_xml.h"
#include "vlc_osd.h"
#include "vlc_meta.h"
#endif
#include <assert.h>
+/*****************************************************************************
+ * Constants
+ *****************************************************************************/
+
+const vlc_destructor_t kVLCDestructor = NULL;
+
/*****************************************************************************
* Local prototypes
*****************************************************************************/
}
p_priv->i_refcount = 1;
+ p_priv->pf_destructor = kVLCDestructor;
+ p_priv->b_thread = VLC_FALSE;
p_new->p_parent = NULL;
p_new->pp_children = NULL;
p_new->i_children = 0;
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";
i_size = sizeof(vout_thread_t);
psz_type = "video output";
break;
- case VLC_OBJECT_SPU:
- i_size = sizeof(spu_t);
- psz_type = "subpicture";
- break;
case VLC_OBJECT_AOUT:
i_size = sizeof(aout_instance_t);
psz_type = "audio output";
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_XML:
- i_size = sizeof( xml_t );
- psz_type = "xml";
- break;
case VLC_OBJECT_OPENGL:
i_size = sizeof( vout_thread_t );
psz_type = "opengl";
}
+/**
+ ****************************************************************************
+ * Set the destructor of a vlc object
+ *
+ * This function sets the destructor of the vlc object. It will be called
+ * when the object is destroyed when the its refcount reaches 0.
+ * (It is called by the internal function vlc_object_destroy())
+ *****************************************************************************/
+void __vlc_object_set_destructor( vlc_object_t *p_this,
+ vlc_destructor_t pf_destructor )
+{
+ vlc_object_internals_t *p_priv = vlc_internals(p_this );
+
+ vlc_mutex_lock( &structure_lock );
+ p_priv->pf_destructor = pf_destructor;
+ vlc_mutex_unlock( &structure_lock );
+}
+
/**
****************************************************************************
* Destroy a vlc object (Internal)
{
vlc_object_internals_t *p_priv = vlc_internals( p_this );
+ /* Automatically detach the object from its parents */
+ if( p_this->p_parent ) vlc_object_detach( p_this );
+
+
+ /* Send a kill to the object's thread if applicable */
+ vlc_object_kill( p_this );
+
+ /* If we are running on a thread, wait until it ends */
+ if( p_priv->b_thread )
+ vlc_thread_join( p_this );
+
+ /* Call the custom "subclass" destructor */
+ if( p_priv->pf_destructor )
+ p_priv->pf_destructor( p_this );
+
/* Sanity checks */
if( p_this->i_children )
{
abort();
}
- if( p_this->p_parent )
- {
- fprintf( stderr,
- "ERROR: cannot delete object (id:%i, type:%s, name:%s) "
- "with a parent (id:%i, type:%s, name:%s)\n",
- p_this->i_object_id, p_this->psz_object_type,
- p_this->psz_object_name, p_this->p_parent->i_object_id,
- p_this->p_parent->psz_object_type,
- p_this->p_parent->psz_object_name );
- fflush(stderr);
- abort();
- }
-
/* Destroy the associated variables, starting from the end so that
* no memmove calls have to be done. */
while( p_priv->i_vars )
else
{
/* This happens when there are only two remaining objects */
- if( pp_objects[i_middle+1]->i_object_id == i_id )
+ if( pp_objects[i_middle+1]->i_object_id == i_id
+ && pp_objects[i_middle+1]->p_internals->i_refcount > 0 )
{
vlc_object_yield_locked( pp_objects[i_middle+1] );
vlc_mutex_unlock( &structure_lock );
break;
}
}
- else
+ else if( pp_objects[i_middle]->p_internals->i_refcount > 0 )
{
vlc_object_yield_locked( pp_objects[i_middle] );
vlc_mutex_unlock( &structure_lock );
vlc_mutex_lock( &structure_lock );
- /* Avoid obvious freed object uses */
- assert( p_this->p_internals->i_refcount > 0 );
-
/* If we are of the requested type ourselves, don't look further */
- if( !(i_mode & FIND_STRICT) && p_this->i_object_type == i_type )
+ if( !(i_mode & FIND_STRICT) && p_this->i_object_type == i_type
+ && p_this->p_internals->i_refcount > 0 )
{
vlc_object_yield_locked( p_this );
vlc_mutex_unlock( &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 ) )
+ && !strcmp( p_this->psz_object_name, psz_name )
+ && p_this->p_internals->i_refcount > 0 )
{
vlc_object_yield_locked( p_this );
vlc_mutex_unlock( &structure_lock );
/* When the structure_lock is locked */
static void vlc_object_yield_locked( vlc_object_t *p_this )
{
+ vlc_assert_locked (&structure_lock);
+
/* Avoid obvious freed object uses */
assert( p_this->p_internals->i_refcount > 0 );
vlc_mutex_lock( &structure_lock );
- /* Avoid obvious freed object uses */
- assert( p_this->p_internals->i_refcount > 0 );
-
if( !p_this->p_parent )
{
msg_Err( p_this, "object is not attached" );
vlc_mutex_lock( &structure_lock );
- /* Avoid obvious freed object uses */
- assert( p_this->p_internals->i_refcount > 0 );
-
/* Look for the objects */
switch( i_mode & 0x000f )
{
p_tmp = p_this->p_parent;
if( p_tmp )
{
- if( p_tmp->i_object_type == i_type )
+ if( p_tmp->i_object_type == i_type
+ && p_tmp->p_internals->i_refcount > 0 )
{
vlc_object_yield_locked( p_tmp );
return p_tmp;
for( i = p_this->i_children; i--; )
{
p_tmp = p_this->pp_children[i];
- if( p_tmp->i_object_type == i_type )
+ if( p_tmp->i_object_type == i_type
+ && p_tmp->p_internals->i_refcount > 0 )
{
vlc_object_yield_locked( p_tmp );
return p_tmp;
if( p_tmp )
{
if( p_tmp->psz_object_name
- && !strcmp( p_tmp->psz_object_name, psz_name ) )
+ && !strcmp( p_tmp->psz_object_name, psz_name )
+ && p_tmp->p_internals->i_refcount > 0 )
{
vlc_object_yield_locked( p_tmp );
return p_tmp;
{
p_tmp = p_this->pp_children[i];
if( p_tmp->psz_object_name
- && !strcmp( p_tmp->psz_object_name, psz_name ) )
+ && !strcmp( p_tmp->psz_object_name, psz_name )
+ && p_tmp->p_internals->i_refcount > 0 )
{
vlc_object_yield_locked( p_tmp );
return p_tmp;