vlc_thread_t thread;
vlc_mutex_t lock;
- vlc_cond_t wait;
+ bool b_live, b_zombie;
int i_art_policy;
int i_waiting;
input_item_t **pp_waiting;
vlc_object_attach( p_fetcher, p_playlist );
p_fetcher->p_playlist = p_playlist;
vlc_mutex_init( &p_fetcher->lock );
- vlc_cond_init( &p_fetcher->wait );
+ p_fetcher->b_live = false;
+ p_fetcher->b_zombie = false;
p_fetcher->i_waiting = 0;
p_fetcher->pp_waiting = NULL;
p_fetcher->i_art_policy = var_GetInteger( p_playlist, "album-art" );
ARRAY_INIT( p_fetcher->albums );
- if( vlc_clone( &p_fetcher->thread, Thread, p_fetcher,
- VLC_THREAD_PRIORITY_LOW ) )
- {
- msg_Err( p_fetcher, "cannot spawn secondary preparse thread" );
- vlc_object_release( p_fetcher );
- return NULL;
- }
-
return p_fetcher;
}
vlc_gc_incref( p_item );
vlc_mutex_lock( &p_fetcher->lock );
+ if( p_fetcher->b_zombie ) /* FIXME: detach the thread */
+ {
+ vlc_join( p_fetcher->thread, NULL );
+ p_fetcher->b_zombie = false;
+ }
+
INSERT_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting,
p_fetcher->i_waiting, p_item );
- vlc_cond_signal( &p_fetcher->wait );
+ if( !p_fetcher->b_live )
+ {
+ if( vlc_clone( &p_fetcher->thread, Thread, p_fetcher,
+ VLC_THREAD_PRIORITY_LOW ) )
+ msg_Err( p_fetcher, "cannot spawn secondary preparse thread" );
+ else
+ p_fetcher->b_live = true;
+ }
vlc_mutex_unlock( &p_fetcher->lock );
}
void playlist_fetcher_Delete( playlist_fetcher_t *p_fetcher )
{
- /* */
- vlc_object_kill( p_fetcher );
-
+ bool b_join;
/* Destroy the item meta-infos fetcher */
- vlc_cancel( p_fetcher->thread );
- vlc_join( p_fetcher->thread, NULL );
+ vlc_mutex_lock( &p_fetcher->lock );
+ if( p_fetcher->b_live )
+ {
+ vlc_object_kill( p_fetcher );
+ vlc_cancel( p_fetcher->thread );
+ }
+ b_join = p_fetcher->b_live || p_fetcher->b_zombie;
+ vlc_mutex_unlock( &p_fetcher->lock );
+ if( b_join )
+ vlc_join( p_fetcher->thread, NULL );
while( p_fetcher->i_waiting > 0 )
{ /* Any left-over unparsed item? */
vlc_gc_decref( p_fetcher->pp_waiting[0] );
REMOVE_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting, 0 );
}
- vlc_cond_destroy( &p_fetcher->wait );
vlc_mutex_destroy( &p_fetcher->lock );
vlc_object_release( p_fetcher );
}
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_this); VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
- playlist_fetcher_t *p_fetcher = p_data;
+ vlc_cond_t *p_cond = p_data;
if( newval.i_int == INPUT_EVENT_ITEM_META ||
newval.i_int == INPUT_EVENT_DEAD )
- vlc_cond_signal( &p_fetcher->wait );
+ vlc_cond_signal( p_cond );
return VLC_SUCCESS;
}
if( input_GetItem( p_input ) != p_item )
goto exit;
- var_AddCallback( p_input, "intf-event", InputEvent, p_fetcher );
+ vlc_cond_t cond;
+ vlc_cond_init( &cond );
+ var_AddCallback( p_input, "intf-event", InputEvent, &cond );
const mtime_t i_deadline = mdate() + 500*1000;
+ bool b_timeout = false;
- while( !p_input->b_eof && !p_input->b_error && !input_item_IsPreparsed( p_item ) )
+ while( !p_input->b_eof && !p_input->b_error
+ && !input_item_IsPreparsed( p_item ) && !b_timeout )
{
- /* A bit weird, but input_item_IsPreparsed does held the protected value */
+ /* A bit weird, but input_item_IsPreparsed holds the protected value */
+ /* FIXME: locking looks wrong here */
vlc_mutex_lock( &p_fetcher->lock );
- vlc_cond_timedwait( &p_fetcher->wait, &p_fetcher->lock, i_deadline );
+ if( vlc_cond_timedwait( &cond, &p_fetcher->lock, i_deadline ) )
+ b_timeout = true;
vlc_mutex_unlock( &p_fetcher->lock );
-
- if( i_deadline <= mdate() )
- break;
}
var_DelCallback( p_input, "intf-event", InputEvent, p_fetcher );
+ vlc_cond_destroy( &cond );
exit:
vlc_object_release( p_input );
for( ;; )
{
- input_item_t *p_item;
+ input_item_t *p_item = NULL;
- /* Be sure to be cancellable before our queue is empty */
- vlc_testcancel();
-
- /* */
vlc_mutex_lock( &p_fetcher->lock );
- mutex_cleanup_push( &p_fetcher->lock );
-
- while( p_fetcher->i_waiting == 0 )
- vlc_cond_wait( &p_fetcher->wait, &p_fetcher->lock );
-
- p_item = p_fetcher->pp_waiting[0];
- REMOVE_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting, 0 );
- vlc_cleanup_run( );
+ if( p_fetcher->i_waiting != 0 )
+ {
+ p_item = p_fetcher->pp_waiting[0];
+ REMOVE_ELEM( p_fetcher->pp_waiting, p_fetcher->i_waiting, 0 );
+ }
+ else
+ {
+ p_fetcher->b_live = false;
+ p_fetcher->b_zombie = true;
+ }
+ vlc_mutex_unlock( &p_fetcher->lock );
if( !p_item )
- continue;
+ break;
/* */
int canc = vlc_savecancel();
int i_activity = var_GetInteger( p_playlist, "activity" );
if( i_activity < 0 ) i_activity = 0;
- /* Sleep at least 1ms */
+ /* Sleep at least 1ms and handle potential thread cancellation */
msleep( (i_activity+1) * 1000 );
}
return NULL;
}
-
-