[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