[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