[vlc-devel] [PATCH] input: preparser: prepare for multithreaded background worker

Filip Roséen filip at atch.se
Tue Jul 17 12:11:28 CEST 2018


As there are plans to make the src/misc/background_worker
multithreaded, the preparser must be changed in order to support
having several tasks running in parallel.

These changes accomplishes said goal by moving the relevant
task related data-members from struct input_preparser_t to a new one,
so that each task has its own state.

--

These changes are only required if the background-worker becomes
multithreaded, as described in the below linked thread.

 - https://mailman.videolan.org/pipermail/vlc-devel/2018-July/120171.html
---
 src/preparser/preparser.c | 83 +++++++++++++++++++++++----------------
 1 file changed, 50 insertions(+), 33 deletions(-)

diff --git a/src/preparser/preparser.c b/src/preparser/preparser.c
index f58a474623..529464e4b8 100644
--- a/src/preparser/preparser.c
+++ b/src/preparser/preparser.c
@@ -36,71 +36,88 @@ struct input_preparser_t
     vlc_object_t* owner;
     input_fetcher_t* fetcher;
     struct background_worker* worker;
-    atomic_int  state;
-    atomic_bool ended;
     atomic_bool deactivated;
 };
 
-static void InputEvent( input_thread_t *input, void *preparser_,
+typedef struct input_preparser_task_t
+{
+    input_preparser_t* preparser;
+    input_thread_t* input;
+    atomic_int state;
+    atomic_bool done;
+
+} input_preparser_task_t;
+
+static void InputEvent( input_thread_t *input, void *task_,
                         const struct vlc_input_event *event )
 {
     VLC_UNUSED( input );
-    input_preparser_t *preparser = preparser_;
+    input_preparser_task_t* task = task_;
 
     switch( event->type )
     {
         case INPUT_EVENT_STATE:
-            atomic_store( &preparser->state, event->state );
+            atomic_store( &task->state, event->state );
             break;
+
         case INPUT_EVENT_DEAD:
-            atomic_store( &preparser->ended, true );
-            background_worker_RequestProbe( preparser->worker );
-            break;
-        default:
+            atomic_store( &task->done, true );
+            background_worker_RequestProbe( task->preparser->worker );
             break;
+        default: ;
     }
 }
 
 static int PreparserOpenInput( void* preparser_, void* item_, void** out )
 {
     input_preparser_t* preparser = preparser_;
+    input_preparser_task_t* task = malloc( sizeof *task );
 
-    atomic_store( &preparser->state, INIT_S );
-    atomic_store( &preparser->ended, false );
-    input_thread_t* input = input_CreatePreparser( preparser->owner, InputEvent,
-                                                   preparser, item_ );
-    if( !input )
-    {
-        input_item_SignalPreparseEnded( item_, ITEM_PREPARSE_FAILED );
-        return VLC_EGENERIC;
-    }
+    if( unlikely( !task ) )
+        goto error;
 
-    if( input_Start( input ) )
+    atomic_init( &task->state, INIT_S );
+    atomic_init( &task->done, false );
+
+    task->preparser = preparser_;
+    task->input = input_CreatePreparser( preparser->owner, InputEvent,
+                                         task, item_ );
+    if( !task->input )
+        goto error;
+
+    if( input_Start( task->input ) )
     {
-        input_Close( input );
-        input_item_SignalPreparseEnded( item_, ITEM_PREPARSE_FAILED );
-        return VLC_EGENERIC;
+        input_Close( task->input );
+        goto error;
     }
 
-    *out = input;
+    *out = task;
+
     return VLC_SUCCESS;
+
+error:
+    free( task );
+    input_item_SignalPreparseEnded( item_, ITEM_PREPARSE_FAILED );
+    return VLC_EGENERIC;
 }
 
-static int PreparserProbeInput( void* preparser_, void* input_ )
+static int PreparserProbeInput( void* preparser_, void* task_ )
 {
-    input_preparser_t* preparser = preparser_;
-    return atomic_load( &preparser->ended );
-    VLC_UNUSED( input_ );
+    input_preparser_task_t* task = task_;
+    return atomic_load( &task->done );
+    VLC_UNUSED( preparser_ );
 }
 
-static void PreparserCloseInput( void* preparser_, void* input_ )
+static void PreparserCloseInput( void* preparser_, void* task_ )
 {
+    input_preparser_task_t* task = task_;
+
     input_preparser_t* preparser = preparser_;
-    input_thread_t* input = input_;
-    input_item_t* item = input_priv(input)->p_item;
+    input_thread_t* input = task->input;
+    input_item_t* item = input_priv(task->input)->p_item;
 
     int status;
-    switch( atomic_load( &preparser->state ) )
+    switch( atomic_load( &task->state ) )
     {
         case END_S:
             status = ITEM_PREPARSE_DONE;
@@ -115,6 +132,8 @@ static void PreparserCloseInput( void* preparser_, void* input_ )
     input_Stop( input );
     input_Close( input );
 
+    free( task );
+
     if( preparser->fetcher )
     {
         if( !input_fetcher_Push( preparser->fetcher, item, 0, status ) )
@@ -152,9 +171,7 @@ input_preparser_t* input_preparser_New( vlc_object_t *parent )
 
     preparser->owner = parent;
     preparser->fetcher = input_fetcher_New( parent );
-    atomic_init( &preparser->state, INIT_S );
     atomic_init( &preparser->deactivated, false );
-    atomic_init( &preparser->ended, false );
 
     if( unlikely( !preparser->fetcher ) )
         msg_Warn( parent, "unable to create art fetcher" );
-- 
2.18.0


More information about the vlc-devel mailing list