Commit 94def855 authored by Thomas Guillem's avatar Thomas Guillem
Browse files

preparser: fix timeout

input_Stop() must be called before input_Close() in case of timeout.

closes #17353
parent 9a108595
......@@ -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 );
}
/**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment