vlc | branch: master | Thomas Guillem <[email protected]> | Tue Sep 27 15:58:53 2016 +0200| [94def8559b5e45cfb58d2d0d477d86a8dab17a98] | committer: Thomas Guillem
preparser: fix timeout input_Stop() must be called before input_Close() in case of timeout. closes #17353 > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=94def8559b5e45cfb58d2d0d477d86a8dab17a98 --- src/playlist/preparser.c | 56 ++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/playlist/preparser.c b/src/playlist/preparser.c index 0dc31e5..e4a219c 100644 --- a/src/playlist/preparser.c +++ b/src/playlist/preparser.c @@ -52,9 +52,13 @@ struct playlist_preparser_t playlist_fetcher_t *p_fetcher; mtime_t default_timeout; - input_thread_t *input; void *input_id; - bool input_done; + enum { + INPUT_INIT, + INPUT_RUNNING, + INPUT_STOPPED, + INPUT_CANCELED, + } input_state; vlc_mutex_t lock; vlc_cond_t wait; @@ -75,9 +79,8 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t *parent ) if( !p_preparser ) return NULL; - p_preparser->input = NULL; p_preparser->input_id = NULL; - p_preparser->input_done = false; + p_preparser->input_state = INPUT_INIT; p_preparser->object = parent; p_preparser->default_timeout = var_InheritInteger( parent, "preparse-timeout" ); p_preparser->p_fetcher = playlist_fetcher_New( parent ); @@ -149,8 +152,8 @@ void playlist_preparser_Cancel( playlist_preparser_t *p_preparser, void *id ) /* Stop the input_thread reading the item (if any) */ if( p_preparser->input_id == id ) { - assert( p_preparser->input != NULL ); - input_Stop( p_preparser->input ); + p_preparser->input_state = INPUT_CANCELED; + vlc_cond_signal( &p_preparser->thread_wait ); } vlc_mutex_unlock( &p_preparser->lock ); } @@ -167,8 +170,8 @@ void playlist_preparser_Delete( playlist_preparser_t *p_preparser ) REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 ); } - if( p_preparser->input != NULL ) - input_Stop( p_preparser->input ); + p_preparser->input_state = INPUT_CANCELED; + vlc_cond_signal( &p_preparser->thread_wait ); while( p_preparser->b_live ) vlc_cond_wait( &p_preparser->wait, &p_preparser->lock ); @@ -196,8 +199,15 @@ static int InputEvent( vlc_object_t *obj, const char *varname, if( event == INPUT_EVENT_DEAD ) { - preparser->input_done = true; - vlc_cond_signal( &preparser->thread_wait ); + vlc_mutex_lock( &preparser->lock ); + + if( preparser->input_state != INPUT_INIT ) + { + preparser->input_state = INPUT_STOPPED; + vlc_cond_signal( &preparser->thread_wait ); + } + + vlc_mutex_unlock( &preparser->lock ); } (void) obj; (void) varname; (void) old; @@ -244,26 +254,29 @@ static void Preparse( playlist_preparser_t *preparser, { vlc_mutex_lock( &preparser->lock ); - preparser->input = input; - preparser->input_done = false; + preparser->input_state = INPUT_RUNNING; preparser->input_id = p_entry->id; if( p_entry->timeout > 0 ) { mtime_t deadline = mdate() + p_entry->timeout; - int ret = 0; - while( !preparser->input_done && ret == 0 ) - ret = vlc_cond_timedwait( &preparser->thread_wait, - &preparser->lock, deadline ); - status = ret == 0 ? ITEM_PREPARSE_DONE : ITEM_PREPARSE_TIMEOUT; + while( preparser->input_state == INPUT_RUNNING ) + { + if( vlc_cond_timedwait( &preparser->thread_wait, + &preparser->lock, deadline ) ) + preparser->input_state = INPUT_CANCELED; /* timeout */ + } } else { - while( !preparser->input_done ) + while( preparser->input_state == INPUT_RUNNING ) vlc_cond_wait( &preparser->thread_wait, &preparser->lock ); - status = ITEM_PREPARSE_DONE; } - preparser->input = NULL; + assert( preparser->input_state == INPUT_STOPPED + || preparser->input_state == INPUT_CANCELED ); + status = preparser->input_state == INPUT_STOPPED ? + ITEM_PREPARSE_DONE : ITEM_PREPARSE_TIMEOUT; + preparser->input_state = INPUT_INIT; preparser->input_id = NULL; vlc_mutex_unlock( &preparser->lock ); @@ -272,6 +285,8 @@ static void Preparse( playlist_preparser_t *preparser, status = ITEM_PREPARSE_FAILED; var_DelCallback( input, "intf-event", InputEvent, preparser ); + if( status == ITEM_PREPARSE_TIMEOUT ) + input_Stop( input ); input_Close( input ); var_SetAddress( preparser->object, "item-change", p_item ); @@ -280,7 +295,6 @@ static void Preparse( playlist_preparser_t *preparser, } else if (!b_preparse) input_item_SignalPreparseEnded( p_item, ITEM_PREPARSE_SKIPPED ); - } /** _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
