* 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 <stdlib.h>
#include <stdarg.h>
+#include <assert.h>
#include <string.h>
#include <stdio.h>
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 )
/*****************************************************************************
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 );
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 );
}
}
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 );
{
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 );
#else
AddItem( p_sd, p_input );
#endif
+ vlc_gc_decref( p_input );
}
#ifdef HAVE_HAL_1
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,
#else
AddItem( p_sd, p_input );
#endif
+ vlc_gc_decref( p_input );
}
static void ParseDevice( services_discovery_t *p_sd, char *psz_device )
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;
}
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;