From: Laurent Aimar Date: Wed, 21 Feb 2007 23:15:06 +0000 (+0000) Subject: Changed input_DestroyThread to take care of detaching, cleaning and destroying input. X-Git-Tag: 0.9.0-test0~8481 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=600e2cd549142370607f55455aa29de0d6d1cd8e;p=vlc Changed input_DestroyThread to take care of detaching, cleaning and destroying input. (This way it matches input_CreateThread and fixes a memleak) Control variables are now created even for preparse, only callback are not added. (This fix use of uninitialized variables) --- diff --git a/modules/services_discovery/podcast.c b/modules/services_discovery/podcast.c index ca3488dabe..976205f8ed 100644 --- a/modules/services_discovery/podcast.c +++ b/modules/services_discovery/podcast.c @@ -200,8 +200,6 @@ static void Close( vlc_object_t *p_this ) { input_StopThread( p_sd->p_sys->pp_input[i] ); input_DestroyThread( p_sd->p_sys->pp_input[i] ); - vlc_object_detach( p_sd->p_sys->pp_input[i] ); - vlc_object_destroy( p_sd->p_sys->pp_input[i] ); p_sd->p_sys->pp_input[i] = NULL; } } @@ -233,8 +231,6 @@ static void Run( services_discovery_t *p_sd ) { input_StopThread( p_sd->p_sys->pp_input[i] ); input_DestroyThread( p_sd->p_sys->pp_input[i] ); - vlc_object_detach( p_sd->p_sys->pp_input[i] ); - vlc_object_destroy( p_sd->p_sys->pp_input[i] ); p_sd->p_sys->pp_input[i] = NULL; } } diff --git a/src/input/input.c b/src/input/input.c index 9f6c1b98d8..81d64d2fc7 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -49,7 +49,7 @@ * Local prototypes *****************************************************************************/ static int Run ( input_thread_t *p_input ); -static int RunAndClean ( input_thread_t *p_input ); +static int RunAndDestroy ( input_thread_t *p_input ); static input_thread_t * Create ( vlc_object_t *, input_item_t *, const char *, vlc_bool_t ); @@ -197,8 +197,7 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, input_ConfigVarInit( p_input ); /* Create Objects variables for public Get and Set */ - if( !p_input->b_preparsing ) - input_ControlVarInit( p_input ); + input_ControlVarInit( p_input ); p_input->p->input.i_cr_average = var_GetInteger( p_input, "cr-average" ); @@ -254,9 +253,25 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, input_Control( p_input, INPUT_DEL_INFO, _(VLC_META_INFO_CAT), VLC_META_NOW_PLAYING ); /* ? Don't translate as it might has been copied ? */ + /* */ + if( p_input->b_preparsing ) + p_input->i_flags |= OBJECT_FLAGS_QUIET | OBJECT_FLAGS_NOINTERACT; + + /* Attach only once we are ready */ + vlc_object_attach( p_input, p_parent ); + return p_input; } +static void Destroy( input_thread_t *p_input ) +{ + vlc_object_detach( p_input ); + + vlc_mutex_destroy( &p_input->p->lock_control ); + free( p_input->p ); + + vlc_object_destroy( p_input ); +} /** * Initialize an input thread and run it. You will need to monitor the * thread to clean up after it is done @@ -282,18 +297,13 @@ input_thread_t *__input_CreateThread2( vlc_object_t *p_parent, if( !p_input ) return NULL; - /* Now we can attach our new input */ - vlc_object_attach( p_input, p_parent ); - /* Create thread and wait for its readiness. */ if( vlc_thread_create( p_input, "input", Run, VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) ) { input_ChangeState( p_input, ERROR_S ); msg_Err( p_input, "cannot create input thread" ); - vlc_object_detach( p_input ); - free( p_input->p ); - vlc_object_destroy( p_input ); + Destroy( p_input ); return NULL; } @@ -318,24 +328,19 @@ int __input_Read( vlc_object_t *p_parent, input_item_t *p_item, if( !p_input ) return VLC_EGENERIC; - /* Now we can attach our new input */ - vlc_object_attach( p_input, p_parent ); - if( b_block ) { - RunAndClean( p_input ); + RunAndDestroy( p_input ); return VLC_SUCCESS; } else { - if( vlc_thread_create( p_input, "input", RunAndClean, + if( vlc_thread_create( p_input, "input", RunAndDestroy, VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) ) { input_ChangeState( p_input, ERROR_S ); msg_Err( p_input, "cannot create input thread" ); - vlc_object_detach( p_input ); - free( p_input->p ); - vlc_object_destroy( p_input ); + Destroy( p_input ); return VLC_EGENERIC; } } @@ -359,23 +364,17 @@ int __input_Preparse( vlc_object_t *p_parent, input_item_t *p_item ) if( !p_input ) return VLC_EGENERIC; - p_input->i_flags |= OBJECT_FLAGS_QUIET; - p_input->i_flags |= OBJECT_FLAGS_NOINTERACT; - - /* Now we can attach our new input */ - vlc_object_attach( p_input, p_parent ); - Init( p_input ); /* Clean up master */ InputSourceClean( p_input, &p_input->p->input ); + /* FIXME shouldn't we call End() to ? */ + /* Unload all modules */ if( p_input->p->p_es_out ) input_EsOutDelete( p_input->p->p_es_out ); - vlc_object_detach( p_input ); - free( p_input->p ); - vlc_object_destroy( p_input ); + Destroy( p_input ); return VLC_SUCCESS; } @@ -434,11 +433,8 @@ void input_DestroyThread( input_thread_t *p_input ) /* Join the thread */ vlc_thread_join( p_input ); - /* Delete input lock (only after thread joined) */ - vlc_mutex_destroy( &p_input->p->lock_control ); - - /* TODO: maybe input_DestroyThread should also delete p_input instead - * of the playlist but I'm not sure if it's possible */ + /* */ + Destroy( p_input ); } /***************************************************************************** @@ -498,20 +494,17 @@ static int Run( input_thread_t *p_input ) } /***************************************************************************** - * RunAndClean: main thread loop + * RunAndDestroy: main thread loop * This is the "just forget me" thread that spawns the input processing chain, * reads the stream, cleans up and releases memory *****************************************************************************/ -static int RunAndClean( input_thread_t *p_input ) +static int RunAndDestroy( input_thread_t *p_input ) { /* Signal that the thread is launched */ vlc_thread_ready( p_input ); if( Init( p_input ) ) - { - /* If we failed, just exit */ - return 0; - } + goto exit; MainLoop( p_input ); @@ -535,11 +528,9 @@ static int RunAndClean( input_thread_t *p_input ) /* Clean up */ End( p_input ); +exit: /* Release memory */ - vlc_object_detach( p_input ); - free( p_input->p ); - vlc_object_destroy( p_input ); - + Destroy( p_input ); return 0; } @@ -1143,14 +1134,11 @@ static void End( input_thread_t * p_input ) { int i; - msg_Dbg( p_input, "closing input" ); - /* We are at the end */ input_ChangeState( p_input, END_S ); /* Clean control variables */ - if( !p_input->b_preparsing ) - input_ControlVarClean( p_input ); + input_ControlVarClean( p_input ); /* Clean up master */ InputSourceClean( p_input, &p_input->p->input ); diff --git a/src/input/var.c b/src/input/var.c index f10493befd..204c692359 100644 --- a/src/input/var.c +++ b/src/input/var.c @@ -75,46 +75,49 @@ void input_ControlVarInit ( input_thread_t *p_input ) { vlc_value_t val, text; + /* XXX we put callback only in non preparsing mode. We need to create the variable + * unless someone want to check all var_Get/var_Change return value ... */ +#define ADD_CALLBACK( name, callback ) do { if( !p_input->b_preparsing ) { var_AddCallback( p_input, name, callback, NULL ); } } while(0) /* State */ var_Create( p_input, "state", VLC_VAR_INTEGER ); val.i_int = p_input->i_state; var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); - var_AddCallback( p_input, "state", StateCallback, NULL ); + ADD_CALLBACK( "state", StateCallback ); /* Rate */ var_Create( p_input, "rate", VLC_VAR_INTEGER ); val.i_int = p_input->p->i_rate; var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL ); - var_AddCallback( p_input, "rate", RateCallback, NULL ); + ADD_CALLBACK( "rate", RateCallback ); var_Create( p_input, "rate-slower", VLC_VAR_VOID ); - var_AddCallback( p_input, "rate-slower", RateCallback, NULL ); + ADD_CALLBACK( "rate-slower", RateCallback ); var_Create( p_input, "rate-faster", VLC_VAR_VOID ); - var_AddCallback( p_input, "rate-faster", RateCallback, NULL ); + ADD_CALLBACK( "rate-faster", RateCallback ); /* Position */ var_Create( p_input, "position", VLC_VAR_FLOAT ); var_Create( p_input, "position-offset", VLC_VAR_FLOAT ); val.f_float = 0.0; var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL ); - var_AddCallback( p_input, "position", PositionCallback, NULL ); - var_AddCallback( p_input, "position-offset", PositionCallback, NULL ); + ADD_CALLBACK( "position", PositionCallback ); + ADD_CALLBACK( "position-offset", PositionCallback ); /* Time */ var_Create( p_input, "time", VLC_VAR_TIME ); var_Create( p_input, "time-offset", VLC_VAR_TIME ); /* relative */ val.i_time = 0; var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL ); - var_AddCallback( p_input, "time", TimeCallback, NULL ); - var_AddCallback( p_input, "time-offset", TimeCallback, NULL ); + ADD_CALLBACK( "time", TimeCallback ); + ADD_CALLBACK( "time-offset", TimeCallback ); /* Bookmark */ var_Create( p_input, "bookmark", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND ); val.psz_string = _("Bookmark"); var_Change( p_input, "bookmark", VLC_VAR_SETTEXT, &val, NULL ); - var_AddCallback( p_input, "bookmark", BookmarkCallback, NULL ); + ADD_CALLBACK( "bookmark", BookmarkCallback ); /* Program */ var_Create( p_input, "program", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE | @@ -124,7 +127,7 @@ void input_ControlVarInit ( input_thread_t *p_input ) var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL ); text.psz_string = _("Program"); var_Change( p_input, "program", VLC_VAR_SETTEXT, &text, NULL ); - var_AddCallback( p_input, "program", ProgramCallback, NULL ); + ADD_CALLBACK( "program", ProgramCallback ); /* Programs */ var_Create( p_input, "programs", VLC_VAR_LIST | VLC_VAR_DOINHERIT ); @@ -135,13 +138,13 @@ void input_ControlVarInit ( input_thread_t *p_input ) var_Create( p_input, "title", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE ); text.psz_string = _("Title"); var_Change( p_input, "title", VLC_VAR_SETTEXT, &text, NULL ); - var_AddCallback( p_input, "title", TitleCallback, NULL ); + ADD_CALLBACK( "title", TitleCallback ); /* Chapter */ var_Create( p_input, "chapter", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE ); text.psz_string = _("Chapter"); var_Change( p_input, "chapter", VLC_VAR_SETTEXT, &text, NULL ); - var_AddCallback( p_input, "chapter", SeekpointCallback, NULL ); + ADD_CALLBACK( "chapter", SeekpointCallback ); /* Navigation The callback is added after */ var_Create( p_input, "navigation", VLC_VAR_VARIABLE | VLC_VAR_HASCHOICE ); @@ -152,29 +155,29 @@ void input_ControlVarInit ( input_thread_t *p_input ) var_Create( p_input, "audio-delay", VLC_VAR_TIME ); val.i_time = 0; var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL ); - var_AddCallback( p_input, "audio-delay", EsDelayCallback, NULL ); + ADD_CALLBACK( "audio-delay", EsDelayCallback ); var_Create( p_input, "spu-delay", VLC_VAR_TIME ); val.i_time = 0; var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL ); - var_AddCallback( p_input, "spu-delay", EsDelayCallback, NULL ); + ADD_CALLBACK( "spu-delay", EsDelayCallback ); /* Video ES */ var_Create( p_input, "video-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE ); text.psz_string = _("Video Track"); var_Change( p_input, "video-es", VLC_VAR_SETTEXT, &text, NULL ); - var_AddCallback( p_input, "video-es", ESCallback, NULL ); + ADD_CALLBACK( "video-es", ESCallback ); /* Audio ES */ var_Create( p_input, "audio-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE ); text.psz_string = _("Audio Track"); var_Change( p_input, "audio-es", VLC_VAR_SETTEXT, &text, NULL ); - var_AddCallback( p_input, "audio-es", ESCallback, NULL ); + ADD_CALLBACK( "audio-es", ESCallback ); /* Spu ES */ var_Create( p_input, "spu-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE ); text.psz_string = _("Subtitles Track"); var_Change( p_input, "spu-es", VLC_VAR_SETTEXT, &text, NULL ); - var_AddCallback( p_input, "spu-es", ESCallback, NULL ); + ADD_CALLBACK( "spu-es", ESCallback ); /* Special read only objects variables for intf */ var_Create( p_input, "bookmarks", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); @@ -183,14 +186,18 @@ void input_ControlVarInit ( input_thread_t *p_input ) val.i_time = 0; var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL ); - /* Special "intf-change" variable, it allows intf to set up a callback - * to be notified of some changes. - * TODO list all changes warn by this callbacks */ - var_Create( p_input, "intf-change", VLC_VAR_BOOL ); - var_SetBool( p_input, "intf-change", VLC_TRUE ); - - /* item-change variable */ - var_Create( p_input, "item-change", VLC_VAR_INTEGER ); + if( !p_input->b_preparsing ) + { + /* Special "intf-change" variable, it allows intf to set up a callback + * to be notified of some changes. + * TODO list all changes warn by this callbacks */ + var_Create( p_input, "intf-change", VLC_VAR_BOOL ); + var_SetBool( p_input, "intf-change", VLC_TRUE ); + + /* item-change variable */ + var_Create( p_input, "item-change", VLC_VAR_INTEGER ); + } +#undef ADD_CALLBACK } /***************************************************************************** diff --git a/src/input/vlm.c b/src/input/vlm.c index 16a0bbee32..d729ac6ac8 100644 --- a/src/input/vlm.c +++ b/src/input/vlm.c @@ -1147,8 +1147,6 @@ int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd, input_StopThread( p_input ); input_DestroyThread( p_input ); - vlc_object_detach( p_input ); - vlc_object_destroy( p_input ); } free( psz_output ); free( psz_header ); @@ -1241,8 +1239,6 @@ int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, const char *psz_id, { input_StopThread( p_instance->p_input ); input_DestroyThread( p_instance->p_input ); - vlc_object_detach( p_instance->p_input ); - vlc_object_destroy( p_instance->p_input ); } asprintf( &psz_header, _("Media: %s"), media->psz_name ); @@ -1362,8 +1358,6 @@ int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, const char *psz_id, { input_StopThread( p_instance->p_input ); input_DestroyThread( p_instance->p_input ); - vlc_object_detach( p_instance->p_input ); - vlc_object_destroy( p_instance->p_input ); } input_ItemClean( &p_instance->item ); @@ -2497,8 +2491,6 @@ static int Manage( vlc_object_t* p_object ) input_StopThread( p_instance->p_input ); input_DestroyThread( p_instance->p_input ); - vlc_object_detach( p_instance->p_input ); - vlc_object_destroy( p_instance->p_input ); p_instance->i_index++; if( p_instance->i_index == p_media->i_input && diff --git a/src/playlist/engine.c b/src/playlist/engine.c index 6b0f500757..85bd955a7d 100644 --- a/src/playlist/engine.c +++ b/src/playlist/engine.c @@ -259,13 +259,6 @@ check_input: /* Destroy input */ input_DestroyThread( p_input ); - /* Unlink current input - * (_after_ input_DestroyThread for vout garbage collector) */ - vlc_object_detach( p_input ); - - /* Destroy object */ - vlc_object_destroy( p_input ); - PL_LOCK; p_playlist->gc_date = mdate(); @@ -389,12 +382,6 @@ void playlist_LastLoop( playlist_t *p_playlist ) /* Destroy input */ input_DestroyThread( p_input ); - /* Unlink current input (_after_ input_DestroyThread for vout - * garbage collector)*/ - vlc_object_detach( p_input ); - - /* Destroy object */ - vlc_object_destroy( p_input ); continue; } else if( p_playlist->p_input->b_die )