vlc | branch: master | Thomas Guillem <[email protected]> | Sat Jun 4 16:22:22 2016 +0200| [f30ae6b016b6dca3a4c072f98486f9e81044ead3] | committer: Thomas Guillem
preparser: interrupt the thread by stopping input_thread_t > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f30ae6b016b6dca3a4c072f98486f9e81044ead3 --- src/playlist/preparser.c | 61 +++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/src/playlist/preparser.c b/src/playlist/preparser.c index 5315dc4..f360a47 100644 --- a/src/playlist/preparser.c +++ b/src/playlist/preparser.c @@ -25,6 +25,8 @@ # include "config.h" #endif +#include <assert.h> + #include <vlc_common.h> #include "fetcher.h" @@ -47,9 +49,12 @@ struct playlist_preparser_t vlc_object_t *object; playlist_fetcher_t *p_fetcher; + input_thread_t *input; + bool input_done; + vlc_mutex_t lock; vlc_cond_t wait; - vlc_sem_t item_done; + vlc_cond_t thread_wait; bool b_live; preparser_entry_t **pp_waiting; int i_waiting; @@ -66,6 +71,8 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t *parent ) if( !p_preparser ) return NULL; + p_preparser->input = NULL; + p_preparser->input_done = false; p_preparser->object = parent; p_preparser->p_fetcher = playlist_fetcher_New( parent ); if( unlikely(p_preparser->p_fetcher == NULL) ) @@ -73,7 +80,7 @@ playlist_preparser_t *playlist_preparser_New( vlc_object_t *parent ) vlc_mutex_init( &p_preparser->lock ); vlc_cond_init( &p_preparser->wait ); - vlc_sem_init( &p_preparser->item_done, 0 ); + vlc_cond_init( &p_preparser->thread_wait ); p_preparser->b_live = false; p_preparser->i_waiting = 0; p_preparser->pp_waiting = NULL; @@ -125,14 +132,15 @@ void playlist_preparser_Delete( playlist_preparser_t *p_preparser ) REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 ); } - vlc_sem_post( &p_preparser->item_done ); + if( p_preparser->input != NULL ) + input_Stop( p_preparser->input ); while( p_preparser->b_live ) vlc_cond_wait( &p_preparser->wait, &p_preparser->lock ); vlc_mutex_unlock( &p_preparser->lock ); /* Destroy the item preparser */ - vlc_sem_destroy( &p_preparser->item_done ); + vlc_cond_destroy( &p_preparser->thread_wait ); vlc_cond_destroy( &p_preparser->wait ); vlc_mutex_destroy( &p_preparser->lock ); @@ -148,11 +156,14 @@ void playlist_preparser_Delete( playlist_preparser_t *p_preparser ) static int InputEvent( vlc_object_t *obj, const char *varname, vlc_value_t old, vlc_value_t cur, void *data ) { - vlc_sem_t *done = data; + playlist_preparser_t *preparser = data; int event = cur.i_int; if( event == INPUT_EVENT_DEAD ) - vlc_sem_post( done ); + { + preparser->input_done = true; + vlc_cond_signal( &preparser->thread_wait ); + } (void) obj; (void) varname; (void) old; return VLC_SUCCESS; @@ -183,25 +194,26 @@ static void Preparse( playlist_preparser_t *preparser, input_item_t *p_item, /* Do not preparse if it is already done (like by playing it) */ if( b_preparse && !input_item_IsPreparsed( p_item ) ) { - input_thread_t *input = input_CreatePreparser( preparser->object, - p_item ); - if( input == NULL ) + preparser->input = input_CreatePreparser( preparser->object, p_item ); + if( preparser->input == NULL ) { input_item_SignalPreparseEnded( p_item, ITEM_PREPARSE_FAILED ); return; } + preparser->input_done = false; + + var_AddCallback( preparser->input, "intf-event", InputEvent, + preparser ); + if( input_Start( preparser->input ) == VLC_SUCCESS ) + { + while( !preparser->input_done ) + vlc_cond_wait( &preparser->thread_wait, &preparser->lock ); + } - var_AddCallback( input, "intf-event", InputEvent, - &preparser->item_done ); - if( input_Start( input ) == VLC_SUCCESS ) - vlc_sem_wait( &preparser->item_done ); - var_DelCallback( input, "intf-event", InputEvent, - &preparser->item_done ); - /* Normally, the input is already stopped since we waited for it. But - * if the playlist preparser is being deleted, then the input might - * still be running. Force it to stop. */ - input_Stop( input ); - input_Close( input ); + var_DelCallback( preparser->input, "intf-event", InputEvent, + preparser ); + input_Close( preparser->input ); + preparser->input = NULL; var_SetAddress( preparser->object, "item-change", p_item ); input_item_SetPreparsed( p_item, true ); @@ -260,13 +272,13 @@ static void *Thread( void *data ) { playlist_preparser_t *p_preparser = data; + vlc_mutex_lock( &p_preparser->lock ); for( ;; ) { input_item_t *p_current; input_item_meta_request_option_t i_options; /* */ - vlc_mutex_lock( &p_preparser->lock ); if( p_preparser->i_waiting > 0 ) { preparser_entry_t *p_entry = p_preparser->pp_waiting[0]; @@ -280,17 +292,16 @@ static void *Thread( void *data ) p_current = NULL; p_preparser->b_live = false; vlc_cond_signal( &p_preparser->wait ); - } - vlc_mutex_unlock( &p_preparser->lock ); - - if( !p_current ) break; + } + assert( p_current ); Preparse( p_preparser, p_current, i_options ); Art( p_preparser, p_current ); vlc_gc_decref(p_current); } + vlc_mutex_unlock( &p_preparser->lock ); return NULL; } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
