]> git.sesse.net Git - vlc/commitdiff
Fixed a race condition with input creation and events.
authorLaurent Aimar <fenrir@videolan.org>
Fri, 8 May 2009 00:03:05 +0000 (02:03 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Fri, 8 May 2009 00:12:39 +0000 (02:12 +0200)
input_CreateThread* have been splitted in two functions:
 - input_Create
 - input_Start
to allow attaching to input events and creating settings/variables
before starting the input thread.

For consistency, input_StopThread has been renamed input_Stop.

Initial report from Hugo Beauzee-Luyssen.

include/vlc_input.h
modules/services_discovery/podcast.c
src/control/media_player.c
src/input/input.c
src/input/input_interface.h
src/input/vlm.c
src/libvlccore.sym
src/playlist/item.c
src/playlist/thread.c

index f7fc5f700c1558059c720e936f2270f25c5b9cab..06f6fc2bf33010d1c238bf601cb5171e897766f5 100644 (file)
@@ -248,14 +248,16 @@ static inline void vlc_input_attachment_Delete( input_attachment_t *a )
 #define INPUT_UPDATE_META       0x0040
 #define INPUT_UPDATE_SIGNAL     0x0080
 
-/** Get the input item for an input thread
- * FIXME see src/input/item.c but is is unsafe unless
- * you hold p_input
+/**
+ * This defines private core storage for an input.
  */
-VLC_EXPORT(input_item_t*, input_GetItem, (input_thread_t*));
-
 typedef struct input_thread_private_t input_thread_private_t;
 
+/**
+ * This defines an opaque input resource handler.
+ */
+typedef struct input_resource_t input_resource_t;
+
 /**
  * Main structure representing an input thread. This structure is mostly
  * private. The only public fields are READ-ONLY. You must use the helpers
@@ -431,32 +433,9 @@ typedef enum input_event_type_e
 
 } input_event_type_e;
 
-/** @}*/
-
-/*****************************************************************************
- * Prototypes
- *****************************************************************************/
-
 /**
- * It will create a new input thread.
- *
- * You must call input_StopThread() on it and then vlc_object_release().
+ * Input queries
  */
-#define input_CreateThread(a,b) __input_CreateThread(VLC_OBJECT(a),b)
-VLC_EXPORT( input_thread_t *, __input_CreateThread, ( vlc_object_t *, input_item_t * ) );
-
-/**
- * It will ask a input_thread_t to stop.
- *
- * b_abort must be true when a user stop is requested and not because you have
- * detected an error or an eof. It will be used to properly send the
- * INPUT_EVENT_ABORT event.
- */
-VLC_EXPORT( void,             input_StopThread,     ( input_thread_t *, bool b_abort ) );
-
-#define input_Read(a,b,c) __input_Read(VLC_OBJECT(a),b, c)
-VLC_EXPORT( int, __input_Read, ( vlc_object_t *, input_item_t *, bool ) );
-
 enum input_query_e
 {
     /* input variable "position" */
@@ -526,9 +505,37 @@ enum input_query_e
     INPUT_GET_VOUTS,        /* arg1=vout_thread_t ***, int *        res=can fail */
 };
 
+/** @}*/
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+
+#define input_Create(a,b,c,d) __input_Create(VLC_OBJECT(a),b,c,d)
+VLC_EXPORT( input_thread_t *, __input_Create, ( vlc_object_t *p_parent, input_item_t *, const char *psz_log, input_resource_t * ) );
+
+#define input_CreateAndStart(a,b,c) __input_CreateAndStart(VLC_OBJECT(a),b,c)
+VLC_EXPORT( input_thread_t *, __input_CreateAndStart, ( vlc_object_t *p_parent, input_item_t *, const char *psz_log ) );
+
+VLC_EXPORT( int,  input_Start, ( input_thread_t * ) );
+
+VLC_EXPORT( void, input_Stop, ( input_thread_t *, bool b_abort ) );
+
+#define input_Read(a,b,c) __input_Read(VLC_OBJECT(a),b, c)
+VLC_EXPORT( int, __input_Read, ( vlc_object_t *, input_item_t *, bool ) );
+
 VLC_EXPORT( int, input_vaControl,( input_thread_t *, int i_query, va_list  ) );
+
 VLC_EXPORT( int, input_Control,  ( input_thread_t *, int i_query, ...  ) );
 
+/**
+ * Get the input item for an input thread
+ *
+ * You have to keep a reference to the input or to the input_item_t until
+ * you do not need it anymore.
+ */
+VLC_EXPORT( input_item_t*, input_GetItem, ( input_thread_t * ) );
+
 /**
  * It will return the current state of the input.
  * Provided for convenience.
@@ -567,7 +574,7 @@ static inline vout_thread_t *input_GetVout( input_thread_t *p_input )
          vlc_object_release( (vlc_object_t *)(pp_vout[i]) );
 
      p_vout = (i_vout >= 1) ? pp_vout[0] : NULL;
-     free (pp_vout);
+     free( pp_vout );
      return p_vout;
 }
 
index 021ca45fc4d1ffbd1e98c216fd3be43dbb27c313..83c92c12bfd7e306fba5d1e9776e7f3f680e495f 100644 (file)
@@ -159,12 +159,15 @@ static void Close( vlc_object_t *p_this )
 
     for( i = 0; i < p_sys->i_input; i++ )
     {
-        if( p_sd->p_sys->pp_input[i] )
-        {
-            input_StopThread( p_sd->p_sys->pp_input[i], true );
-            vlc_object_release( p_sd->p_sys->pp_input[i] );
-            p_sd->p_sys->pp_input[i] = NULL;
-        }
+        input_thread_t *p_input = p_sd->p_sys->pp_input[i];
+        if( !p_input )
+            continue;
+
+        input_Stop( p_input, true );
+        vlc_thread_join( p_input );
+        vlc_object_release( p_input );
+
+        p_sd->p_sys->pp_input[i] = NULL;
     }
     free( p_sd->p_sys->pp_input );
     for( i = 0; i < p_sys->i_urls; i++ ) free( p_sys->ppsz_urls[i] );
@@ -197,11 +200,14 @@ static void *Run( void *data )
 
         for( int i = 0; i < p_sd->p_sys->i_input; i++ )
         {
-            if( p_sd->p_sys->pp_input[i]->b_eof
-                || p_sd->p_sys->pp_input[i]->b_error )
+            input_thread_t *p_input = p_sd->p_sys->pp_input[i];
+
+            if( p_input->b_eof || p_input->b_error )
             {
-                input_StopThread( p_sd->p_sys->pp_input[i], false );
-                vlc_object_release( p_sd->p_sys->pp_input[i] );
+                input_Stop( p_input, false );
+                vlc_thread_join( p_input );
+                vlc_object_release( p_input );
+
                 p_sd->p_sys->pp_input[i] = NULL;
                 REMOVE_ELEM( p_sys->pp_input, p_sys->i_input, i );
                 i--;
@@ -253,7 +259,7 @@ static void ParseUrls( services_discovery_t *p_sd, char *psz_urls )
             services_discovery_AddItem( p_sd, p_input, NULL /* no cat */ );
             vlc_gc_decref( p_input );
             INSERT_ELEM( p_sys->pp_input, p_sys->i_input, p_sys->i_input,
-                         input_CreateThread( p_sd, p_input ) );
+                         input_CreateAndStart( p_sd, p_input, NULL ) );
         }
         if( psz_tok )  psz_urls = psz_tok+1;
         else           return;
index 3eb1c1e94ae51ce339275fbb596f89dd36927032..19dd794043008563943341bc7788a9eb3f678678 100644 (file)
@@ -89,7 +89,7 @@ static void release_input_thread( libvlc_media_player_t *p_mi, bool b_input_abor
                          input_event_changed, p_mi );
 
         /* We owned this one */
-        input_StopThread( p_input_thread, b_input_abort );
+        input_Stop( p_input_thread, b_input_abort );
         vlc_thread_join( p_input_thread );
 
         var_Destroy( p_input_thread, "drawable-hwnd" );
@@ -606,8 +606,8 @@ void libvlc_media_player_play( libvlc_media_player_t *p_mi,
         return;
     }
 
-    p_mi->p_input_thread = input_CreateThread(
-            p_mi->p_libvlc_instance->p_libvlc_int, p_mi->p_md->p_input_item );
+    p_mi->p_input_thread = input_Create( p_mi->p_libvlc_instance->p_libvlc_int,
+                                         p_mi->p_md->p_input_item, NULL, NULL );
 
     if( !p_mi->p_input_thread )
     {
@@ -643,6 +643,12 @@ void libvlc_media_player_play( libvlc_media_player_t *p_mi,
     var_AddCallback( p_input_thread, "can-pause", input_pausable_changed, p_mi );
     var_AddCallback( p_input_thread, "intf-event", input_event_changed, p_mi );
 
+    if( input_Start( p_input_thread ) )
+    {
+        vlc_object_release( p_input_thread );
+        p_mi->p_input_thread = NULL;
+    }
+
     vlc_mutex_unlock( &p_mi->object_lock );
 }
 
@@ -717,7 +723,7 @@ void libvlc_media_player_stop( libvlc_media_player_t *p_mi,
         if( !p_input_thread )
             return;
 
-        input_StopThread( p_input_thread, true );
+        input_Stop( p_input_thread, true );
         vlc_object_release( p_input_thread );
         p_mi->p_input_thread = NULL;
     }
index 3f51cf58b6746d49a816e4aa1d0e330af5642ec5..396994b2674a52cb6f2b67d4519293718bef1c68 100644 (file)
@@ -113,6 +113,200 @@ static void input_ChangeState( input_thread_t *p_input, int i_state ); /* TODO f
 /* Do not let a pts_delay from access/demux go beyong 60s */
 #define INPUT_PTS_DELAY_MAX INT64_C(60000000)
 
+/**
+ * Create a new input_thread_t.
+ *
+ * You need to call input_Start on it when you are done
+ * adding callback on the variables/events you want to monitor.
+ *
+ * \param p_parent a vlc_object
+ * \param p_item an input item
+ * \param psz_log an optional prefix for this input logs
+ * \param p_resource an optional input ressource
+ * \return a pointer to the spawned input thread
+ */
+
+input_thread_t *__input_Create( vlc_object_t *p_parent,
+                                input_item_t *p_item,
+                                const char *psz_log, input_resource_t *p_resource )
+{
+
+    return Create( p_parent, p_item, psz_log, false, p_resource );
+}
+
+/**
+ * Create a new input_thread_t and start it.
+ *
+ * Provided for convenience.
+ *
+ * \see input_Create
+ */
+input_thread_t *__input_CreateAndStart( vlc_object_t *p_parent,
+                                        input_item_t *p_item, const char *psz_log )
+{
+    input_thread_t *p_input = __input_Create( p_parent, p_item, psz_log, NULL );
+
+    if( input_Start( p_input ) )
+    {
+        vlc_object_release( p_input );
+        return NULL;
+    }
+    return p_input;
+}
+
+/**
+ * Initialize an input thread and run it. This thread will clean after itself,
+ * you can forget about it. It can work either in blocking or non-blocking mode
+ *
+ * \param p_parent a vlc_object
+ * \param p_item an input item
+ * \param b_block should we block until read is finished ?
+ * \return an error code, VLC_SUCCESS on success
+ */
+int __input_Read( vlc_object_t *p_parent, input_item_t *p_item,
+                   bool b_block )
+{
+    input_thread_t *p_input;
+
+    p_input = Create( p_parent, p_item, NULL, false, NULL );
+    if( !p_input )
+        return VLC_EGENERIC;
+
+    if( b_block )
+    {
+        RunAndDestroy( VLC_OBJECT(p_input) );
+        return VLC_SUCCESS;
+    }
+    else
+    {
+        if( vlc_thread_create( p_input, "input", RunAndDestroy,
+                               VLC_THREAD_PRIORITY_INPUT ) )
+        {
+            input_ChangeState( p_input, ERROR_S );
+            msg_Err( p_input, "cannot create input thread" );
+            vlc_object_release( p_input );
+            return VLC_EGENERIC;
+        }
+    }
+    return VLC_SUCCESS;
+}
+
+/**
+ * Initialize an input and initialize it to preparse the item
+ * This function is blocking. It will only accept parsing regular files.
+ *
+ * \param p_parent a vlc_object_t
+ * \param p_item an input item
+ * \return VLC_SUCCESS or an error
+ */
+int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
+{
+    input_thread_t *p_input;
+
+    /* Allocate descriptor */
+    p_input = Create( p_parent, p_item, NULL, true, NULL );
+    if( !p_input )
+        return VLC_EGENERIC;
+
+    if( !Init( p_input ) )
+        End( p_input );
+
+    vlc_object_release( p_input );
+
+    return VLC_SUCCESS;
+}
+
+/**
+ * Start a input_thread_t created by input_Create.
+ *
+ * You must not start an already running input_thread_t.
+ *
+ * \param the input thread to start
+ */
+int input_Start( input_thread_t *p_input )
+{
+    /* Create thread and wait for its readiness. */
+    if( vlc_thread_create( p_input, "input", Run,
+                           VLC_THREAD_PRIORITY_INPUT ) )
+    {
+        input_ChangeState( p_input, ERROR_S );
+        msg_Err( p_input, "cannot create input thread" );
+        return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
+/**
+ * Request a running input thread to stop and die
+ *
+ * b_abort must be true when a user stop is requested and not because you have
+ * detected an error or an eof. It will be used to properly send the
+ * INPUT_EVENT_ABORT event.
+ *
+ * \param p_input the input thread to stop
+ * \param b_abort true if the input has been aborted by a user request
+ */
+void input_Stop( input_thread_t *p_input, bool b_abort )
+{
+    /* Set die for input and ALL of this childrens (even (grand-)grand-childrens)
+     * It is needed here even if it is done in INPUT_CONTROL_SET_DIE handler to
+     * unlock the control loop */
+    ObjectKillChildrens( p_input, VLC_OBJECT(p_input) );
+
+    vlc_mutex_lock( &p_input->p->lock_control );
+    p_input->p->b_abort |= b_abort;
+    vlc_mutex_unlock( &p_input->p->lock_control );
+
+    input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
+}
+
+input_resource_t *input_DetachResource( input_thread_t *p_input )
+{
+    assert( p_input->b_dead );
+
+    input_resource_SetInput( p_input->p->p_resource, NULL );
+
+    input_resource_t *p_resource = input_resource_Detach( p_input->p->p_resource );
+    p_input->p->p_sout = NULL;
+
+    return p_resource;
+}
+
+/**
+ * Get the item from an input thread
+ * FIXME it does not increase ref count of the item.
+ * if it is used after p_input is destroyed nothing prevent it from
+ * being freed.
+ */
+input_item_t *input_GetItem( input_thread_t *p_input )
+{
+    assert( p_input && p_input->p );
+    return p_input->p->p_item;
+}
+
+/*****************************************************************************
+ * ObjectKillChildrens
+ *****************************************************************************/
+static void ObjectKillChildrens( input_thread_t *p_input, vlc_object_t *p_obj )
+{
+    vlc_list_t *p_list;
+    int i;
+
+    /* FIXME ObjectKillChildrens seems a very bad idea in fact */
+    i = vlc_internals( p_obj )->i_object_type;
+    if( i == VLC_OBJECT_VOUT ||i == VLC_OBJECT_AOUT ||
+        p_obj == VLC_OBJECT(p_input->p->p_sout) ||
+        i == VLC_OBJECT_DECODER || i == VLC_OBJECT_PACKETIZER )
+        return;
+
+    vlc_object_kill( p_obj );
+
+    p_list = vlc_list_children( p_obj );
+    for( i = 0; i < p_list->i_count; i++ )
+        ObjectKillChildrens( p_input, p_list->p_values[i].p_object );
+    vlc_list_release( p_list );
+}
+
 /*****************************************************************************
  * This function creates a new input, and returns a pointer
  * to its description. On error, it returns NULL.
@@ -333,174 +527,6 @@ static void Destructor( input_thread_t * p_input )
     free( p_input->p );
 }
 
-/**
- * Initialize an input thread and run it. You will need to monitor the
- * thread to clean up after it is done
- *
- * \param p_parent a vlc_object
- * \param p_item an input item
- * \return a pointer to the spawned input thread
- */
-input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
-                                      input_item_t *p_item )
-{
-    return __input_CreateThreadExtended( p_parent, p_item, NULL, NULL );
-}
-
-/* */
-input_thread_t *__input_CreateThreadExtended( vlc_object_t *p_parent,
-                                              input_item_t *p_item,
-                                              const char *psz_log, input_resource_t *p_resource )
-{
-    input_thread_t *p_input;
-
-    p_input = Create( p_parent, p_item, psz_log, false, p_resource );
-    if( !p_input )
-        return NULL;
-
-    /* Create thread and wait for its readiness. */
-    if( vlc_thread_create( p_input, "input", Run,
-                           VLC_THREAD_PRIORITY_INPUT ) )
-    {
-        input_ChangeState( p_input, ERROR_S );
-        msg_Err( p_input, "cannot create input thread" );
-        vlc_object_detach( p_input );
-        vlc_object_release( p_input );
-        return NULL;
-    }
-
-    return p_input;
-}
-
-/**
- * Initialize an input thread and run it. This thread will clean after itself,
- * you can forget about it. It can work either in blocking or non-blocking mode
- *
- * \param p_parent a vlc_object
- * \param p_item an input item
- * \param b_block should we block until read is finished ?
- * \return an error code, VLC_SUCCESS on success
- */
-int __input_Read( vlc_object_t *p_parent, input_item_t *p_item,
-                   bool b_block )
-{
-    input_thread_t *p_input;
-
-    p_input = Create( p_parent, p_item, NULL, false, NULL );
-    if( !p_input )
-        return VLC_EGENERIC;
-
-    if( b_block )
-    {
-        RunAndDestroy( VLC_OBJECT(p_input) );
-        return VLC_SUCCESS;
-    }
-    else
-    {
-        if( vlc_thread_create( p_input, "input", RunAndDestroy,
-                               VLC_THREAD_PRIORITY_INPUT ) )
-        {
-            input_ChangeState( p_input, ERROR_S );
-            msg_Err( p_input, "cannot create input thread" );
-            vlc_object_release( p_input );
-            return VLC_EGENERIC;
-        }
-    }
-    return VLC_SUCCESS;
-}
-
-/**
- * Initialize an input and initialize it to preparse the item
- * This function is blocking. It will only accept parsing regular files.
- *
- * \param p_parent a vlc_object_t
- * \param p_item an input item
- * \return VLC_SUCCESS or an error
- */
-int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
-{
-    input_thread_t *p_input;
-
-    /* Allocate descriptor */
-    p_input = Create( p_parent, p_item, NULL, true, NULL );
-    if( !p_input )
-        return VLC_EGENERIC;
-
-    if( !Init( p_input ) )
-        End( p_input );
-
-    vlc_object_detach( p_input );
-    vlc_object_release( p_input );
-
-    return VLC_SUCCESS;
-}
-
-/**
- * Request a running input thread to stop and die
- *
- * \param the input thread to stop
- */
-void input_StopThread( input_thread_t *p_input, bool b_abort )
-{
-    /* Set die for input and ALL of this childrens (even (grand-)grand-childrens)
-     * It is needed here even if it is done in INPUT_CONTROL_SET_DIE handler to
-     * unlock the control loop */
-    ObjectKillChildrens( p_input, VLC_OBJECT(p_input) );
-
-    vlc_mutex_lock( &p_input->p->lock_control );
-    p_input->p->b_abort |= b_abort;
-    vlc_mutex_unlock( &p_input->p->lock_control );
-
-    input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
-}
-
-input_resource_t *input_DetachResource( input_thread_t *p_input )
-{
-    assert( p_input->b_dead );
-
-    input_resource_SetInput( p_input->p->p_resource, NULL );
-
-    input_resource_t *p_resource = input_resource_Detach( p_input->p->p_resource );
-    p_input->p->p_sout = NULL;
-
-    return p_resource;
-}
-
-/**
- * Get the item from an input thread
- * FIXME it does not increase ref count of the item.
- * if it is used after p_input is destroyed nothing prevent it from
- * being freed.
- */
-input_item_t *input_GetItem( input_thread_t *p_input )
-{
-    assert( p_input && p_input->p );
-    return p_input->p->p_item;
-}
-
-/*****************************************************************************
- * ObjectKillChildrens
- *****************************************************************************/
-static void ObjectKillChildrens( input_thread_t *p_input, vlc_object_t *p_obj )
-{
-    vlc_list_t *p_list;
-    int i;
-
-    /* FIXME ObjectKillChildrens seems a very bad idea in fact */
-    i = vlc_internals( p_obj )->i_object_type;
-    if( i == VLC_OBJECT_VOUT ||i == VLC_OBJECT_AOUT ||
-        p_obj == VLC_OBJECT(p_input->p->p_sout) ||
-        i == VLC_OBJECT_DECODER || i == VLC_OBJECT_PACKETIZER )
-        return;
-
-    vlc_object_kill( p_obj );
-
-    p_list = vlc_list_children( p_obj );
-    for( i = 0; i < p_list->i_count; i++ )
-        ObjectKillChildrens( p_input, p_list->p_values[i].p_object );
-    vlc_list_release( p_list );
-}
-
 /*****************************************************************************
  * Run: main thread loop
  * This is the "normal" thread that spawns the input processing chain,
index dc43bb1b51d7dc7afb227eea7753fec989112853..b7cde94803ffc461e2869f64b09e2c5f7d4323c6 100644 (file)
@@ -46,11 +46,6 @@ int input_Preparse( vlc_object_t *, input_item_t * );
  * FIXME it should NOT be defined here or not coded in misc/stats.c */
 input_stats_t *stats_NewInputStats( input_thread_t *p_input );
 
-/**
- * This defines an opaque input resource handler.
- */
-typedef struct input_resource_t input_resource_t;
-
 /**
  * This function releases an input_resource_t and all associated resources.
  */
@@ -74,8 +69,6 @@ void input_resource_TerminateVout( input_resource_t *p_resource );
 bool input_resource_HasVout( input_resource_t *p_resource );
 
 /* input.c */
-#define input_CreateThreadExtended(a,b,c,d) __input_CreateThreadExtended(VLC_OBJECT(a),b,c,d)
-input_thread_t *__input_CreateThreadExtended ( vlc_object_t *, input_item_t *, const char *, input_resource_t * );
 
 /**
  * This function detaches resources from a dead input.
index a3baba0df7163adcad25a908716f477e47eaee22..c7cf2693c7815909aca13c876190f0abea389ed6 100644 (file)
@@ -531,12 +531,12 @@ static int vlm_OnMediaUpdate( vlm_t *p_vlm, vlm_media_sys_t *p_media )
             if( asprintf( &psz_header, _("Media: %s"), p_cfg->psz_name ) == -1 )
                 psz_header = NULL;
 
-            if( (p_input = input_CreateThreadExtended( p_vlm->p_libvlc, p_media->vod.p_item, psz_header, NULL ) ) )
+            if( (p_input = input_CreateAndStart( p_vlm->p_libvlc, p_media->vod.p_item, psz_header ) ) )
             {
                 while( !p_input->b_eof && !p_input->b_error )
                     msleep( 100000 );
 
-                input_StopThread( p_input, false );
+                input_Stop( p_input, false );
                 vlc_thread_join( p_input );
                 vlc_object_release( p_input );
             }
@@ -778,7 +778,7 @@ static void vlm_MediaInstanceDelete( vlm_t *p_vlm, int64_t id, vlm_media_instanc
     {
         input_resource_t *p_resource;
 
-        input_StopThread( p_input, true );
+        input_Stop( p_input, true );
         vlc_thread_join( p_input );
 
         p_resource = input_DetachResource( p_input );
@@ -861,7 +861,7 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char *
             return VLC_SUCCESS;
         }
 
-        input_StopThread( p_input, !p_input->b_eof && !p_input->b_error );
+        input_Stop( p_input, !p_input->b_eof && !p_input->b_error );
         vlc_thread_join( p_input );
 
         p_instance->p_input_resource = input_DetachResource( p_input );
@@ -881,8 +881,13 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char *
 
     if( asprintf( &psz_log, _("Media: %s"), p_media->cfg.psz_name ) != -1 )
     {
-        p_instance->p_input = input_CreateThreadExtended( p_vlm->p_libvlc, p_instance->p_item,
-                                                          psz_log, p_instance->p_input_resource );
+        p_instance->p_input = input_Create( p_vlm->p_libvlc, p_instance->p_item,
+                                            psz_log, p_instance->p_input_resource );
+        if( p_instance->p_input && input_Start( p_instance->p_input ) )
+        {
+            vlc_object_release( p_instance->p_input );
+            p_instance->p_input = NULL;
+        }
         p_instance->p_input_resource = NULL;
 
         if( !p_instance->p_input )
index 9f7c950c86b8fac2310905596d29888c1b006c3c..ac68b0e2e3b64d329d094ef43fcef5b3786be1e2 100644 (file)
@@ -169,8 +169,9 @@ image_Mime2Fourcc
 image_Type2Fourcc
 InitMD5
 input_Control
+__input_Create
+__input_CreateAndStart
 input_CreateFilename
-__input_CreateThread
 input_DecoderDecode
 input_DecoderDelete
 input_DecoderNew
@@ -199,7 +200,8 @@ input_item_SetURI
 input_MetaTypeToLocalizedString
 __input_Read
 input_SplitMRL
-input_StopThread
+input_Start
+input_Stop
 input_vaControl
 __intf_Create
 __intf_Eject
index a993b79251bb15ed7c31ae55eb7004d89883ea8a..122411e0670282dd3054cc9c8cdb4c04fc18cd74 100644 (file)
@@ -823,7 +823,7 @@ static void GoAndPreparse( playlist_t *p_playlist, int i_mode,
         pl_priv(p_playlist)->request.i_skip = 0;
         pl_priv(p_playlist)->request.p_item = p_toplay;
         if( pl_priv(p_playlist)->p_input )
-            input_StopThread( pl_priv(p_playlist)->p_input, true );
+            input_Stop( pl_priv(p_playlist)->p_input, true );
         pl_priv(p_playlist)->request.i_status = PLAYLIST_RUNNING;
         vlc_cond_signal( &pl_priv(p_playlist)->signal );
     }
index 62e1d74861c2f67b956ae08745761a926a9d7efd..eacfd379f37ff5b52fd86a79efa340e543b574de 100644 (file)
@@ -251,14 +251,17 @@ static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
 
     assert( p_sys->p_input == NULL );
 
-    input_thread_t *p_input_thread =
-        input_CreateThreadExtended( p_playlist, p_input, NULL, p_sys->p_input_resource );
-
+    input_thread_t *p_input_thread = input_Create( p_playlist, p_input, NULL, p_sys->p_input_resource );
     if( p_input_thread )
     {
         p_sys->p_input = p_input_thread;
-
         var_AddCallback( p_input_thread, "intf-event", InputEvent, p_playlist );
+
+        if( input_Start( p_sys->p_input ) )
+        {
+            vlc_object_release( p_input_thread );
+            p_sys->p_input = p_input_thread = NULL;
+        }
     }
 
     p_sys->p_input_resource = NULL;
@@ -473,7 +476,7 @@ static int LoopInput( playlist_t *p_playlist )
     if( ( p_sys->request.b_request || !vlc_object_alive( p_playlist ) ) && !p_input->b_die )
     {
         PL_DEBUG( "incoming request - stopping current input" );
-        input_StopThread( p_input, true );
+        input_Stop( p_input, true );
     }
 
     /* This input is dead. Remove it ! */
@@ -514,7 +517,7 @@ static int LoopInput( playlist_t *p_playlist )
     else if( p_input->b_error || p_input->b_eof )
     {
         PL_DEBUG( "finished input" );
-        input_StopThread( p_input, false );
+        input_Stop( p_input, false );
     }
     return VLC_SUCCESS;
 }