[vlc-devel] [PATCH] input: preparser: prepare for multithreaded background worker
Romain Vimont
rom1v at videolabs.io
Tue Jul 17 12:46:50 CEST 2018
On Tue, Jul 17, 2018 at 12:11:28PM +0200, Filip Roséen wrote:
> 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
LGTM. And thanks for this patch :)
More information about the vlc-devel
mailing list