Changed input_DestroyThread to take care of detaching, cleaning and destroying input.
authorLaurent Aimar <fenrir@videolan.org>
Wed, 21 Feb 2007 23:15:06 +0000 (23:15 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Wed, 21 Feb 2007 23:15:06 +0000 (23:15 +0000)
(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)

modules/services_discovery/podcast.c
src/input/input.c
src/input/var.c
src/input/vlm.c
src/playlist/engine.c

index ca3488d..976205f 100644 (file)
@@ -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;
             }
         }
index 9f6c1b9..81d64d2 100644 (file)
@@ -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 );
index f10493b..204c692 100644 (file)
@@ -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
 }
 
 /*****************************************************************************
index 16a0bbe..d729ac6 100644 (file)
@@ -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 &&
index 6b0f500..85bd955 100644 (file)
@@ -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 )