/*****************************************************************************
* Local structure lock
*****************************************************************************/
-static vlc_mutex_t structure_lock;
+static vlc_mutex_t structure_lock;
+static unsigned object_counter = 0;
-void *vlc_custom_create( vlc_object_t *p_this, size_t i_size,
- int i_type, const char *psz_type )
+void *__vlc_custom_create( vlc_object_t *p_this, size_t i_size,
+ int i_type, const char *psz_type )
{
vlc_object_t *p_new;
vlc_object_internals_t *p_priv;
p_libvlc_global = (libvlc_global_data_t *)p_new;
p_new->p_libvlc = NULL;
- p_libvlc_global->i_counter = 0;
+ object_counter = 0; /* reset */
p_priv->next = p_priv->prev = p_new;
vlc_mutex_init( &structure_lock );
#ifdef LIBVLC_REFCHECK
p_priv->prev = vlc_internals (p_libvlc_global)->prev;
vlc_internals (p_libvlc_global)->prev = p_new;
vlc_internals (p_priv->prev)->next = p_new;
- p_new->i_object_id = p_libvlc_global->i_counter++;
+ p_new->i_object_id = object_counter++; /* fetch THEN increment */
vlc_mutex_unlock( &structure_lock );
if( i_type == VLC_OBJECT_LIBVLC )
switch( i_type )
{
- case VLC_OBJECT_LIBVLC:
- i_size = sizeof(libvlc_int_t);
- psz_type = "libvlc";
- 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";
- break;
case VLC_OBJECT_DECODER:
i_size = sizeof(decoder_t);
psz_type = "decoder";
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_AOUT:
i_size = sizeof(aout_instance_t);
psz_type = "audio output";
i_size = sizeof( announce_handler_t );
psz_type = "announce";
break;
- case VLC_OBJECT_INTERACTION:
- i_size = sizeof( interaction_t );
- psz_type = "interaction";
- break;
default:
- i_size = i_type > (int)sizeof(vlc_object_t)
- ? i_type : (int)sizeof(vlc_object_t);
+ assert( i_type > 0 ); /* unknown type?! */
+ i_size = i_type;
i_type = VLC_OBJECT_GENERIC;
psz_type = "generic";
break;
/* 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 );
+ /* Any thread must have been cleaned up at this point. */
+ assert( !p_priv->b_thread );
+
/* Destroy the associated variables, starting from the end so that
* no memmove calls have to be done. */
while( p_priv->i_vars )
if( p_this->p_libvlc == NULL )
{
+#ifndef NDEBUG
libvlc_global_data_t *p_global = (libvlc_global_data_t *)p_this;
-#ifndef NDEBUG
assert( p_global == vlc_global() );
/* Test for leaks */
if (p_priv->next != p_this)
}
-/**
- * Checks whether an object has been "killed".
- * The object lock must be held.
- *
- * Typical code for an object thread could be:
- *
- vlc_object_lock (self);
- ...initialization...
- while (vlc_object_alive (self))
- {
- ...preprocessing...
-
- vlc_object_wait (self);
-
- ...postprocessing...
- }
- ...deinitialization...
- vlc_object_unlock (self);
- *
- *
- * @return true iff the object has not been killed yet
- */
-bool __vlc_object_alive( vlc_object_t *obj )
-{
- vlc_assert_locked( &(vlc_internals(obj)->lock) );
- return !obj->b_die;
-}
-
-
/**
* Signals an object for which the lock is held.
* At least one thread currently sleeping in vlc_object_wait() or
*/
void __vlc_object_kill( vlc_object_t *p_this )
{
- vlc_object_internals_t *internals = vlc_internals( p_this );
+ vlc_object_internals_t *priv = vlc_internals( p_this );
int fd;
vlc_object_lock( p_this );
p_this->b_die = true;
- vlc_spin_lock (&internals->spin);
- fd = internals->pipes[1];
- internals->pipes[1] = -1;
- vlc_spin_unlock (&internals->spin);
+ vlc_spin_lock (&priv->spin);
+ fd = priv->pipes[1];
+ priv->pipes[1] = -1;
+ vlc_spin_unlock (&priv->spin);
if( fd != -1 )
{
}
vlc_object_signal_unlocked( p_this );
+ /* This also serves as a memory barrier toward vlc_object_alive(): */
vlc_object_unlock( p_this );
-
- if (p_this->i_object_type == VLC_OBJECT_LIBVLC)
- {
- vlc_list_t *children = vlc_list_children (p_this);
- for (int i = 0; i < children->i_count; i++)
- vlc_object_kill (children->p_values[i].p_object);
- vlc_list_release (children);
- }
}