vlc_common.h:
authorPierre d'Herbemont <pdherbemont@videolan.org>
Sun, 23 Dec 2007 14:19:00 +0000 (14:19 +0000)
committerPierre d'Herbemont <pdherbemont@videolan.org>
Sun, 23 Dec 2007 14:19:00 +0000 (14:19 +0000)
* Add some proper assert() to the vlc_gc_* function to spot errors.
* Correctly initialize the refcount to 1. (This will prevent freed pointer usage). (This may also introduce leaks in some module).
modules/*.c:
* Prevent some module to leak input_item_t.

include/vlc_common.h
modules/misc/lua/vlc.c
modules/services_discovery/bonjour.c
modules/services_discovery/freebox.c
modules/services_discovery/hal.c
modules/services_discovery/sap.c
modules/services_discovery/shout.c

index aaf9814..fa177d5 100644 (file)
@@ -63,6 +63,7 @@
  *****************************************************************************/
 #include <stdlib.h>
 #include <stdarg.h>
+#include <assert.h>
 
 #include <string.h>
 #include <stdio.h>
@@ -610,25 +611,38 @@ struct gc_object_t
 
 static inline void __vlc_gc_incref( gc_object_t * p_gc )
 {
+    assert( p_gc->i_gc_refcount > 0 );
+
     p_gc->i_gc_refcount ++;
 };
 
 static inline void __vlc_gc_decref( gc_object_t *p_gc )
 {
+    if( !p_gc ) return;
+
+    assert( p_gc->i_gc_refcount > 0 );
+
     p_gc->i_gc_refcount -- ;
 
     if( p_gc->i_gc_refcount == 0 )
     {
         p_gc->pf_destructor( p_gc );
         /* Do not use the p_gc pointer from now on ! */
-     }
+    }
+}
+
+static inline void
+__vlc_gc_init( gc_object_t * p_gc, void (*pf_destructor)( gc_object_t * ),
+               void * arg)
+{
+    p_gc->i_gc_refcount = 1;
+    p_gc->pf_destructor = pf_destructor;
+    p_gc->p_destructor_arg = arg;
 }
 
 #define vlc_gc_incref( a ) __vlc_gc_incref( (gc_object_t *)a )
 #define vlc_gc_decref( a ) __vlc_gc_decref( (gc_object_t *)a )
-#define vlc_gc_init( a,b,c ) {  ((gc_object_t *)a)->i_gc_refcount = 0; \
-                              ((gc_object_t *)a)->pf_destructor = b; \
-                              ((gc_object_t *)a)->p_destructor_arg = c; }
+#define vlc_gc_init( a,b,c ) __vlc_gc_init( (gc_object_t *)a,b,c )
 
 
 /*****************************************************************************
index fa686a6..cd0fac0 100644 (file)
@@ -753,7 +753,7 @@ int __vlclua_playlist_add_internal( vlc_object_t *p_this, lua_State *L,
                                            PLAYLIST_APPEND | PLAYLIST_PREPARSE,
                                            PLAYLIST_END, VLC_TRUE, VLC_FALSE );
                     i_count ++; /* increment counter */
-
+                    vlc_gc_decref( p_input );
                     while( i_options > 0 )
                         free( ppsz_options[--i_options] );
                     free( ppsz_options );
index 2c65863..d582683 100644 (file)
@@ -189,6 +189,7 @@ static void resolve_callback(
             vlc_dictionary_insert( &p_sys->services_name_to_input_item,
                 name, p_input );
             services_discovery_AddItem( p_sd, p_input, NULL /* no category */ );
+            vlc_gc_decref( p_input );
        }
     }
 
index 8df50c9..45ec03e 100644 (file)
@@ -88,7 +88,6 @@ static void Run( services_discovery_t *p_sd )
     input_item_t * p_input = input_ItemNewExt( p_sd, kpsz_freebox_playlist_url,
                                 _("Freebox TV"), 0, NULL, -1 );
     input_ItemAddOption( p_input, "no-playlist-autostart" );
-    vlc_gc_incref( p_input );
 
     vlc_event_attach( &p_input->event_manager, vlc_InputItemSubItemAdded, ItemAdded, p_sd );
     input_Read( p_sd, p_input, VLC_TRUE );
index f877936..00ebc8f 100644 (file)
@@ -201,6 +201,7 @@ static void AddItem( services_discovery_t *p_sd, input_item_t * p_input
     {
         return;
     }
+    vlc_gc_incref( p_input );
     p_udi_entry->p_item = p_input;
     p_udi_entry->psz_udi = strdup( psz_device );
     TAB_APPEND( p_sys->i_devices_number, p_sys->pp_devices, p_udi_entry );
@@ -238,6 +239,7 @@ static void AddDvd( services_discovery_t *p_sd, char *psz_device )
 #else
     AddItem( p_sd, p_input );
 #endif
+    vlc_gc_decref( p_input );
 }
 
 #ifdef HAVE_HAL_1
@@ -251,6 +253,7 @@ static void DelItem( services_discovery_t *p_sd, char* psz_udi )
         if( strcmp( psz_udi, p_sys->pp_devices[i]->psz_udi ) == 0 )
         { /* delete the corresponding item */    
             services_discovery_RemoveItem( p_sd, p_sys->pp_devices[i]->p_item );
+            vlc_gc_decref( p_sys->pp_devices[i]->p_item );
             if( p_sys->pp_devices[i]->psz_udi )
                 free( p_sys->pp_devices[i]->psz_udi );
             TAB_REMOVE( p_sys->i_devices_number, p_sys->pp_devices,
@@ -284,6 +287,7 @@ static void AddCdda( services_discovery_t *p_sd, char *psz_device )
 #else
     AddItem( p_sd, p_input );
 #endif
+    vlc_gc_decref( p_input );
 }
 
 static void ParseDevice( services_discovery_t *p_sd, char *psz_device )
index 78223da..92e8947 100644 (file)
@@ -895,7 +895,7 @@ sap_announce_t *CreateAnnounce( services_discovery_t *p_sd, uint16_t i_hash,
     services_discovery_AddItem( p_sd, p_input, psz_value /* category name */ );
 
     TAB_APPEND( p_sys->i_announces, p_sys->pp_announces, p_sap );
-
+    vlc_gc_decref( p_input );
     return p_sap;
 }
 
index 230bbbd..a0c0adf 100644 (file)
@@ -139,8 +139,6 @@ static int Open( vlc_object_t *p_this, int i_type )
                                 0, NULL, -1 );
             break;
     }
-    vlc_gc_incref( p_sys->p_input ); /* Refcount to 1, so we can release it
-                                      * in Close() */
 
     input_ItemAddOption( p_sys->p_input, "no-playlist-autostart" );
     return VLC_SUCCESS;