]> git.sesse.net Git - vlc/blobdiff - src/misc/objects.c
* Some more fixes (+ don't redefine a function that already existed, reverts part...
[vlc] / src / misc / objects.c
index 3dbb394ca3807cc55a8801106c05f0225d247a1d..2ce0126ef4f8d3de1a3b019d12cf6ccc93b785a9 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * objects.c: vlc_object_t handling
  *****************************************************************************
- * Copyright (C) 2004 the VideoLAN team
+ * Copyright (C) 2004-2007 the VideoLAN team
  * $Id$
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
@@ -55,6 +55,7 @@
 
 #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"
@@ -70,6 +71,7 @@ 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 vlc_object_t * FindObjectName( vlc_object_t *, const char *, int );
 static void           DetachObject  ( vlc_object_t * );
 static void           PrintObject   ( vlc_object_t *, const char * );
 static void           DumpStructure ( vlc_object_t *, int, char * );
@@ -90,7 +92,7 @@ static vlc_mutex_t    structure_lock;
 vlc_object_t *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_t * p_new = NULL;
 
     if( i_type == VLC_OBJECT_GLOBAL )
     {
@@ -137,32 +139,33 @@ vlc_object_t *vlc_custom_create( vlc_object_t *p_this, size_t i_size,
     if( i_type == VLC_OBJECT_GLOBAL )
     {
         /* If i_type is global, then p_new is actually p_libvlc_global */
-        p_new->p_libvlc_global = (libvlc_global_data_t*)p_new;
+        libvlc_global_data_t *p_libvlc_global = (libvlc_global_data_t *)p_new;
+        p_new->p_libvlc_global = p_new;
         p_new->p_libvlc = NULL;
 
-        p_new->p_libvlc_global->i_counter = 0;
+        p_libvlc_global->i_counter = 0;
         p_new->i_object_id = 0;
 
-        p_new->p_libvlc_global->i_objects = 1;
-        p_new->p_libvlc_global->pp_objects = malloc( sizeof(vlc_object_t *) );
-        p_new->p_libvlc_global->pp_objects[0] = p_new;
+        p_libvlc_global->i_objects = 1;
+        p_libvlc_global->pp_objects = malloc( sizeof(vlc_object_t *) );
+        p_libvlc_global->pp_objects[0] = p_new;
         p_new->b_attached = VLC_TRUE;
     }
     else
     {
-        p_new->p_libvlc_global = p_this->p_libvlc_global;
+        libvlc_global_data_t *p_libvlc_global = vlc_global( p_this );
+        p_new->p_libvlc_global = VLC_OBJECT (p_libvlc_global);
         p_new->p_libvlc = ( i_type == VLC_OBJECT_LIBVLC ) ? (libvlc_int_t*)p_new
                                                        : p_this->p_libvlc;
 
         vlc_mutex_lock( &structure_lock );
 
-        p_new->p_libvlc_global->i_counter++;
-        p_new->i_object_id = p_new->p_libvlc_global->i_counter;
+        p_libvlc_global->i_counter++;
+        p_new->i_object_id = p_libvlc_global->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. */
-        TAB_APPEND( p_new->p_libvlc_global->i_objects,
-                    p_new->p_libvlc_global->pp_objects,
+        TAB_APPEND( p_libvlc_global->i_objects, p_libvlc_global->pp_objects,
                     p_new );
 
         vlc_mutex_unlock( &structure_lock );
@@ -219,10 +222,6 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
             i_size = sizeof(libvlc_int_t);
             psz_type = "libvlc";
             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";
@@ -247,10 +246,6 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
             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";
@@ -401,25 +396,27 @@ void __vlc_object_destroy( vlc_object_t *p_this )
 
     if( p_this->i_object_type == VLC_OBJECT_GLOBAL )
     {
+        libvlc_global_data_t *p_global = (libvlc_global_data_t *)p_this;
         /* We are the global object ... no need to lock. */
-        free( p_this->p_libvlc_global->pp_objects );
-        p_this->p_libvlc_global->pp_objects = NULL;
-        p_this->p_libvlc_global->i_objects--;
+        free( p_global->pp_objects );
+        p_global->pp_objects = NULL;
+        p_global->i_objects--;
 
         vlc_mutex_destroy( &structure_lock );
     }
     else
     {
+        libvlc_global_data_t *p_libvlc_global = vlc_global( p_this );
         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_global->pp_objects,
-                             p_this->p_libvlc_global->i_objects );
-        REMOVE_ELEM( p_this->p_libvlc_global->pp_objects,
-                     p_this->p_libvlc_global->i_objects, i_index );
+        i_index = FindIndex( p_this, p_libvlc_global->pp_objects,
+                             p_libvlc_global->i_objects );
+        REMOVE_ELEM( p_libvlc_global->pp_objects,
+                     p_libvlc_global->i_objects, i_index );
 
         vlc_mutex_unlock( &structure_lock );
     }
@@ -429,9 +426,38 @@ void __vlc_object_destroy( vlc_object_t *p_this )
 
     /* global is not dynamically allocated by vlc_object_create */
     if( p_this->i_object_type != VLC_OBJECT_GLOBAL )
+    {
         free( p_this );
+        p_this = NULL;
+    }
+}
+
+
+void __vlc_object_kill( vlc_object_t *p_this )
+{
+    vlc_mutex_lock( &p_this->object_lock );
+    p_this->b_die = VLC_TRUE;
+    vlc_mutex_unlock( &p_this->object_lock );
+}
+
+
+vlc_bool_t __vlc_object_dying_unlocked( vlc_object_t *p_this )
+{
+    vlc_assert_locked( &p_this->object_lock );
+    return p_this->b_die;
+}
+
+
+vlc_bool_t __vlc_object_dying( vlc_object_t *p_this )
+{
+     vlc_bool_t b;
+     vlc_mutex_lock( &p_this->object_lock );
+     b = __vlc_object_dying_unlocked( p_this );
+     vlc_mutex_unlock( &p_this->object_lock );
+     return b;
 }
 
+
 /**
  * find an object given its ID
  *
@@ -442,13 +468,14 @@ void * __vlc_object_get( vlc_object_t *p_this, int i_id )
 {
     int i_max, i_middle;
     vlc_object_t **pp_objects;
+    libvlc_global_data_t *p_libvlc_global = vlc_global( p_this );
 
     vlc_mutex_lock( &structure_lock );
 
-    pp_objects = p_this->p_libvlc_global->pp_objects;
+    pp_objects = p_libvlc_global->pp_objects;
 
     /* Perform our dichotomy */
-    for( i_max = p_this->p_libvlc_global->i_objects - 1 ; ; )
+    for( i_max = p_libvlc_global->i_objects - 1 ; ; )
     {
         i_middle = i_max / 2;
 
@@ -544,6 +571,60 @@ void * __vlc_object_find( vlc_object_t *p_this, int i_type, int i_mode )
     return p_found;
 }
 
+/**
+ ****************************************************************************
+ * find a named object and increment its refcount
+ *****************************************************************************
+ * This function recursively looks for a given object name. i_mode can be one
+ * of FIND_PARENT, FIND_CHILD or FIND_ANYWHERE.
+ *****************************************************************************/
+void * __vlc_object_find_name( vlc_object_t *p_this, const char *psz_name,
+                               int i_mode )
+{
+    vlc_object_t *p_found;
+
+    vlc_mutex_lock( &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 ) )
+    {
+        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_libvlc ) )
+        {
+            p_root = p_root->p_parent;
+        }
+
+        p_found = FindObjectName( p_root, psz_name,
+                                 (i_mode & ~0x000f)|FIND_CHILD );
+        if( p_found == NULL && p_root != VLC_OBJECT( p_this->p_libvlc ) )
+        {
+            p_found = FindObjectName( VLC_OBJECT( p_this->p_libvlc ),
+                                      psz_name, (i_mode & ~0x000f)|FIND_CHILD );
+        }
+    }
+    else
+    {
+        p_found = FindObjectName( p_this, psz_name, i_mode );
+    }
+
+    vlc_mutex_unlock( &structure_lock );
+
+    return p_found;
+}
+
 /**
  ****************************************************************************
  * increment an object refcount
@@ -575,6 +656,8 @@ void __vlc_object_release( vlc_object_t *p_this )
  *****************************************************************************/
 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 */
@@ -601,6 +684,8 @@ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent )
  *****************************************************************************/
 void __vlc_object_detach( vlc_object_t *p_this )
 {
+    if( !p_this ) return;
+
     vlc_mutex_lock( &structure_lock );
     if( !p_this->p_parent )
     {
@@ -617,6 +702,7 @@ void __vlc_object_detach( vlc_object_t *p_this )
 
     DetachObject( p_this );
     vlc_mutex_unlock( &structure_lock );
+    p_this = NULL;
 }
 
 /**
@@ -631,6 +717,7 @@ 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;
+    libvlc_global_data_t *p_libvlc_global = vlc_global( p_this );
 
     vlc_mutex_lock( &structure_lock );
 
@@ -638,8 +725,8 @@ vlc_list_t * __vlc_list_find( vlc_object_t *p_this, int i_type, int i_mode )
     switch( i_mode & 0x000f )
     {
     case FIND_ANYWHERE:
-        pp_current = p_this->p_libvlc_global->pp_objects;
-        pp_end = pp_current + p_this->p_libvlc_global->i_objects;
+        pp_current = p_libvlc_global->pp_objects;
+        pp_end = pp_current + p_libvlc_global->i_objects;
 
         for( ; pp_current < pp_end ; pp_current++ )
         {
@@ -651,7 +738,7 @@ vlc_list_t * __vlc_list_find( vlc_object_t *p_this, int i_type, int i_mode )
         }
 
         p_list = NewList( i_count );
-        pp_current = p_this->p_libvlc_global->pp_objects;
+        pp_current = p_libvlc_global->pp_objects;
 
         for( ; pp_current < pp_end ; pp_current++ )
         {
@@ -701,14 +788,17 @@ vlc_list_t * __vlc_list_find( vlc_object_t *p_this, int i_type, int i_mode )
 static int DumpCommand( vlc_object_t *p_this, char const *psz_cmd,
                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
+    libvlc_global_data_t *p_libvlc_global = vlc_global( p_this );
+
+    (void)oldval; (void)p_data;
     if( *psz_cmd == 'l' )
     {
         vlc_mutex_lock( &structure_lock );
 
         vlc_object_t **pp_current, **pp_end;
 
-        pp_current = p_this->p_libvlc_global->pp_objects;
-        pp_end = pp_current + p_this->p_libvlc_global->i_objects;
+        pp_current = p_libvlc_global->pp_objects;
+        pp_end = pp_current + p_libvlc_global->i_objects;
 
         for( ; pp_current < pp_end ; pp_current++ )
         {
@@ -732,7 +822,30 @@ static int DumpCommand( vlc_object_t *p_this, char const *psz_cmd,
 
         if( *newval.psz_string )
         {
-            p_object = vlc_object_get( p_this, atoi(newval.psz_string) );
+            char *end;
+            int i_id = strtol( newval.psz_string, &end, 0 );
+            if( end != newval.psz_string )
+                p_object = vlc_object_get( p_this, i_id );
+            else
+            {
+                /* try using the object's name to find it */
+                vlc_object_t *p_libvlc = vlc_object_get( p_this, 1 );
+                if( p_libvlc )
+                {
+                    /* Look in p_libvlc's children tree */
+                    p_object = vlc_object_find_name( p_libvlc,
+                                                     newval.psz_string,
+                                                     FIND_CHILD );
+                    vlc_object_release( p_libvlc );
+                }
+                if( !p_object )
+                {
+                    /* If it's not in libvlc, look in libvlc_global (== p_this) */
+                    p_object = vlc_object_find_name( p_this,
+                                                     newval.psz_string,
+                                                     FIND_CHILD );
+                }
+            }
 
             if( !p_object )
             {
@@ -956,6 +1069,61 @@ static vlc_object_t * FindObject( vlc_object_t *p_this, int i_type, int i_mode )
     return NULL;
 }
 
+static vlc_object_t * FindObjectName( vlc_object_t *p_this,
+                                      const char *psz_name,
+                                      int i_mode )
+{
+    int i;
+    vlc_object_t *p_tmp;
+
+    switch( i_mode & 0x000f )
+    {
+    case FIND_PARENT:
+        p_tmp = p_this->p_parent;
+        if( p_tmp )
+        {
+            if( p_tmp->psz_object_name
+                && !strcmp( p_tmp->psz_object_name, psz_name ) )
+            {
+                p_tmp->i_refcount++;
+                return p_tmp;
+            }
+            else
+            {
+                return FindObjectName( p_tmp, psz_name, i_mode );
+            }
+        }
+        break;
+
+    case FIND_CHILD:
+        for( i = p_this->i_children; i--; )
+        {
+            p_tmp = p_this->pp_children[i];
+            if( p_tmp->psz_object_name
+                && !strcmp( p_tmp->psz_object_name, psz_name ) )
+            {
+                p_tmp->i_refcount++;
+                return p_tmp;
+            }
+            else if( p_tmp->i_children )
+            {
+                p_tmp = FindObjectName( p_tmp, psz_name, i_mode );
+                if( p_tmp )
+                {
+                    return p_tmp;
+                }
+            }
+        }
+        break;
+
+    case FIND_ANYWHERE:
+        /* Handled in vlc_object_find */
+        break;
+    }
+
+    return NULL;
+}
+
 static void DetachObject( vlc_object_t *p_this )
 {
     vlc_object_t *p_parent = p_this->p_parent;
@@ -1015,12 +1183,9 @@ static void PrintObject( vlc_object_t *p_this, const char *psz_prefix )
     psz_name[0] = '\0';
     if( p_this->psz_object_name )
     {
-        snprintf( psz_name, 50, " \"%s\"", p_this->psz_object_name );
+        snprintf( psz_name, 49, " \"%s\"", p_this->psz_object_name );
         if( psz_name[48] )
-        {
             psz_name[48] = '\"';
-            psz_name[49] = '\0';
-        }
     }
 
     psz_children[0] = '\0';
@@ -1032,32 +1197,21 @@ static void PrintObject( vlc_object_t *p_this, const char *psz_prefix )
             strcpy( psz_children, ", 1 child" );
             break;
         default:
-            snprintf( psz_children, 20,
-                      ", %i children", p_this->i_children );
-            psz_children[19] = '\0';
+            snprintf( psz_children, 19, ", %i children", p_this->i_children );
             break;
     }
 
     psz_refcount[0] = '\0';
     if( p_this->i_refcount )
-    {
-        snprintf( psz_refcount, 20, ", refcount %i", p_this->i_refcount );
-        psz_refcount[19] = '\0';
-    }
+        snprintf( psz_refcount, 19, ", refcount %i", p_this->i_refcount );
 
     psz_thread[0] = '\0';
     if( p_this->b_thread )
-    {
-        snprintf( psz_thread, 30, " (thread %d)", (int)p_this->thread_id );
-        psz_thread[29] = '\0';
-    }
+        snprintf( psz_thread, 29, " (thread %d)", (int)p_this->thread_id );
 
     psz_parent[0] = '\0';
     if( p_this->p_parent )
-    {
-        snprintf( psz_parent, 20, ", parent %i", p_this->p_parent->i_object_id );
-        psz_parent[19] = '\0';
-    }
+        snprintf( psz_parent, 19, ", parent %i", p_this->p_parent->i_object_id );
 
     printf( " %so %.8i %s%s%s%s%s%s\n", psz_prefix,
             p_this->i_object_id, p_this->psz_object_type,