Commit 2d3be24e authored by Clément Stenac's avatar Clément Stenac

Don't loop continuously the playlist thread, use cond.

Not tested heavily yet ...

For interaction implementers: you need to call playlist_Signal after changing the status of a dialog. Please see the diff for qt4/dialogs/interaction.cpp
parent 0f382e74
...@@ -137,8 +137,8 @@ struct playlist_t ...@@ -137,8 +137,8 @@ struct playlist_t
* with the current item */ * with the current item */
int i_sort; /**< Last sorting applied to the playlist */ int i_sort; /**< Last sorting applied to the playlist */
int i_order; /**< Last ordering applied to the playlist */ int i_order; /**< Last ordering applied to the playlist */
mtime_t i_vout_destroyed_date; mtime_t gc_date;
mtime_t i_sout_destroyed_date; vlc_bool_t b_cant_sleep;
playlist_preparse_t *p_preparse; /**< Preparser object */ playlist_preparse_t *p_preparse; /**< Preparser object */
playlist_secondary_preparse_t *p_secondary_preparse;/**< Preparser object */ playlist_secondary_preparse_t *p_secondary_preparse;/**< Preparser object */
...@@ -433,6 +433,14 @@ static inline vlc_bool_t playlist_IsEmpty( playlist_t * p_playlist ) ...@@ -433,6 +433,14 @@ static inline vlc_bool_t playlist_IsEmpty( playlist_t * p_playlist )
return( b_empty ); return( b_empty );
} }
/** Ask the playlist to do some work */
static inline void playlist_Signal( playlist_t *p_playlist )
{
PL_LOCK;
vlc_cond_signal( &p_playlist->object_wait );
PL_UNLOCK;
}
/** /**
* @} * @}
*/ */
......
...@@ -195,4 +195,5 @@ void InteractionDialog::Finish( int i_ret ) ...@@ -195,4 +195,5 @@ void InteractionDialog::Finish( int i_ret )
p_dialog->i_return = i_ret; p_dialog->i_return = i_ret;
hide(); hide();
vlc_mutex_unlock( &p_dialog->p_interaction->object_lock ); vlc_mutex_unlock( &p_dialog->p_interaction->object_lock );
playlist_Signal( THEPL );
} }
...@@ -380,7 +380,7 @@ void input_StopThread( input_thread_t *p_input ) ...@@ -380,7 +380,7 @@ void input_StopThread( input_thread_t *p_input )
/* Set die for input */ /* Set die for input */
p_input->b_die = VLC_TRUE; p_input->b_die = VLC_TRUE;
/* We cannot touch p_input fields directly (we can from another thread), /* We cannot touch p_input fields directly (we come from another thread),
* so use the vlc_object_find way, it's perfectly safe */ * so use the vlc_object_find way, it's perfectly safe */
/* Set die for all access */ /* Set die for all access */
...@@ -442,6 +442,7 @@ static int Run( input_thread_t *p_input ) ...@@ -442,6 +442,7 @@ static int Run( input_thread_t *p_input )
{ {
/* If we failed, wait before we are killed, and exit */ /* If we failed, wait before we are killed, and exit */
p_input->b_error = VLC_TRUE; p_input->b_error = VLC_TRUE;
playlist_Signal( pl_Get( p_input ) );
Error( p_input ); Error( p_input );
...@@ -468,6 +469,7 @@ static int Run( input_thread_t *p_input ) ...@@ -468,6 +469,7 @@ static int Run( input_thread_t *p_input )
/* We have finished */ /* We have finished */
p_input->b_eof = VLC_TRUE; p_input->b_eof = VLC_TRUE;
playlist_Signal( pl_Get( p_input ) );
} }
/* Wait until we are asked to die */ /* Wait until we are asked to die */
......
...@@ -102,19 +102,13 @@ void intf_InteractionManage( playlist_t *p_playlist ) ...@@ -102,19 +102,13 @@ void intf_InteractionManage( playlist_t *p_playlist )
// Pretend we have hidden and destroyed it // Pretend we have hidden and destroyed it
if( p_dialog->i_status == HIDDEN_DIALOG ) if( p_dialog->i_status == HIDDEN_DIALOG )
{
p_dialog->i_status = DESTROYED_DIALOG; p_dialog->i_status = DESTROYED_DIALOG;
}
else else
{
p_dialog->i_status = HIDING_DIALOG; p_dialog->i_status = HIDING_DIALOG;
} }
} }
}
else else
{
vlc_object_yield( p_interaction->p_intf ); vlc_object_yield( p_interaction->p_intf );
}
for( i_index = 0 ; i_index < p_interaction->i_dialogs; i_index ++ ) for( i_index = 0 ; i_index < p_interaction->i_dialogs; i_index ++ )
{ {
...@@ -525,11 +519,11 @@ static interaction_dialog_t *DialogGetById( interaction_t *p_interaction, ...@@ -525,11 +519,11 @@ static interaction_dialog_t *DialogGetById( interaction_t *p_interaction,
/* Destroy a dialog */ /* Destroy a dialog */
static void DialogDestroy( interaction_dialog_t *p_dialog ) static void DialogDestroy( interaction_dialog_t *p_dialog )
{ {
FREENULL( p_dialog->psz_title ); free( p_dialog->psz_title );
FREENULL( p_dialog->psz_description ); free( p_dialog->psz_description );
FREENULL( p_dialog->psz_default_button ); free( p_dialog->psz_default_button );
FREENULL( p_dialog->psz_alternate_button ); free( p_dialog->psz_alternate_button );
FREENULL( p_dialog->psz_other_button ); free( p_dialog->psz_other_button );
free( p_dialog ); free( p_dialog );
} }
...@@ -575,6 +569,7 @@ static int DialogSend( vlc_object_t *p_this, interaction_dialog_t *p_dialog ) ...@@ -575,6 +569,7 @@ static int DialogSend( vlc_object_t *p_this, interaction_dialog_t *p_dialog )
if( p_dialog->i_type == INTERACT_DIALOG_TWOWAY ) // Wait for answer if( p_dialog->i_type == INTERACT_DIALOG_TWOWAY ) // Wait for answer
{ {
playlist_Signal( pl_Get(p_this) );
while( p_dialog->i_status != ANSWERED_DIALOG && while( p_dialog->i_status != ANSWERED_DIALOG &&
p_dialog->i_status != HIDING_DIALOG && p_dialog->i_status != HIDING_DIALOG &&
p_dialog->i_status != HIDDEN_DIALOG && p_dialog->i_status != HIDDEN_DIALOG &&
...@@ -591,6 +586,7 @@ static int DialogSend( vlc_object_t *p_this, interaction_dialog_t *p_dialog ) ...@@ -591,6 +586,7 @@ static int DialogSend( vlc_object_t *p_this, interaction_dialog_t *p_dialog )
} }
p_dialog->i_flags |= DIALOG_GOT_ANSWER; p_dialog->i_flags |= DIALOG_GOT_ANSWER;
vlc_mutex_unlock( &p_interaction->object_lock ); vlc_mutex_unlock( &p_interaction->object_lock );
playlist_Signal( pl_Get(p_this) );
return p_dialog->i_return; return p_dialog->i_return;
} }
else else
...@@ -598,6 +594,7 @@ static int DialogSend( vlc_object_t *p_this, interaction_dialog_t *p_dialog ) ...@@ -598,6 +594,7 @@ static int DialogSend( vlc_object_t *p_this, interaction_dialog_t *p_dialog )
// Pretend we already retrieved the "answer" // Pretend we already retrieved the "answer"
p_dialog->i_flags |= DIALOG_GOT_ANSWER; p_dialog->i_flags |= DIALOG_GOT_ANSWER;
vlc_mutex_unlock( &p_interaction->object_lock ); vlc_mutex_unlock( &p_interaction->object_lock );
playlist_Signal( pl_Get(p_this) );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
} }
......
...@@ -179,6 +179,7 @@ int PlaylistVAControl( playlist_t * p_playlist, int i_query, va_list args ) ...@@ -179,6 +179,7 @@ int PlaylistVAControl( playlist_t * p_playlist, int i_query, va_list args )
return VLC_EBADVAR; return VLC_EBADVAR;
break; break;
} }
vlc_cond_signal( &p_playlist->object_wait );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
...@@ -70,8 +70,8 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) ...@@ -70,8 +70,8 @@ playlist_t * playlist_Create( vlc_object_t *p_parent )
p_playlist->i_last_input_id = 0; p_playlist->i_last_input_id = 0;
p_playlist->p_input = NULL; p_playlist->p_input = NULL;
p_playlist->i_vout_destroyed_date = 0; p_playlist->gc_date = 0;
p_playlist->i_sout_destroyed_date = 0; p_playlist->b_cant_sleep = VLC_FALSE;
ARRAY_INIT( p_playlist->items ); ARRAY_INIT( p_playlist->items );
ARRAY_INIT( p_playlist->all_items ); ARRAY_INIT( p_playlist->all_items );
...@@ -194,46 +194,47 @@ void playlist_Destroy( playlist_t *p_playlist ) ...@@ -194,46 +194,47 @@ void playlist_Destroy( playlist_t *p_playlist )
vlc_object_destroy( p_playlist ); vlc_object_destroy( p_playlist );
} }
/* Destroy remaining objects */ /* Destroy remaining objects */
static mtime_t ObjectGarbageCollector( playlist_t *p_playlist, int i_type, static void ObjectGarbageCollector( playlist_t *p_playlist )
mtime_t destroy_date )
{ {
vlc_object_t *p_obj; vlc_object_t *p_obj;
if( destroy_date > mdate() ) return destroy_date; if( mdate() - p_playlist->gc_date < 1000000 )
if( destroy_date == 0 )
{ {
/* give a little time */ p_playlist->b_cant_sleep = VLC_TRUE;
return mdate() + I64C(1000000); return;
} }
else else if( p_playlist->gc_date == 0 )
{ return;
vlc_mutex_lock( &p_playlist->gc_lock ); vlc_mutex_lock( &p_playlist->gc_lock );
while( ( p_obj = vlc_object_find( p_playlist, i_type, FIND_CHILD ) ) ) while( ( p_obj = vlc_object_find( p_playlist, VLC_OBJECT_VOUT,
FIND_CHILD ) ) )
{ {
if( p_obj->p_parent != (vlc_object_t*)p_playlist ) if( p_obj->p_parent != (vlc_object_t*)p_playlist )
{ {
/* only first child (ie unused) */
vlc_object_release( p_obj ); vlc_object_release( p_obj );
break; break;
} }
if( i_type == VLC_OBJECT_VOUT )
{
msg_Dbg( p_playlist, "garbage collector destroying 1 vout" ); msg_Dbg( p_playlist, "garbage collector destroying 1 vout" );
vlc_object_detach( p_obj ); vlc_object_detach( p_obj );
vlc_object_release( p_obj ); vlc_object_release( p_obj );
vout_Destroy( (vout_thread_t *)p_obj ); vout_Destroy( (vout_thread_t *)p_obj );
} }
else if( i_type == VLC_OBJECT_SOUT ) while( ( p_obj = vlc_object_find( p_playlist, VLC_OBJECT_SOUT,
FIND_CHILD ) ) )
{
if( p_obj->p_parent != (vlc_object_t*)p_playlist )
{ {
vlc_object_release( p_obj ); vlc_object_release( p_obj );
sout_DeleteInstance( (sout_instance_t*)p_obj ); break;
} }
vlc_object_release( p_obj );
sout_DeleteInstance( (sout_instance_t*)p_obj );
} }
p_playlist->b_cant_sleep = VLC_FALSE;
vlc_mutex_unlock( &p_playlist->gc_lock ); vlc_mutex_unlock( &p_playlist->gc_lock );
return 0;
}
} }
/** Main loop for the playlist */ /** Main loop for the playlist */
...@@ -244,7 +245,6 @@ void playlist_MainLoop( playlist_t *p_playlist ) ...@@ -244,7 +245,6 @@ void playlist_MainLoop( playlist_t *p_playlist )
PL_LOCK; PL_LOCK;
/* First, check if we have something to do */ /* First, check if we have something to do */
/* FIXME : this can be called several times */
if( p_playlist->request.b_request ) if( p_playlist->request.b_request )
{ {
/* Stop the existing input */ /* Stop the existing input */
...@@ -254,7 +254,7 @@ void playlist_MainLoop( playlist_t *p_playlist ) ...@@ -254,7 +254,7 @@ void playlist_MainLoop( playlist_t *p_playlist )
input_StopThread( p_playlist->p_input ); input_StopThread( p_playlist->p_input );
} }
} }
check_input:
/* If there is an input, check that it doesn't need to die. */ /* If there is an input, check that it doesn't need to die. */
if( p_playlist->p_input ) if( p_playlist->p_input )
{ {
...@@ -282,8 +282,10 @@ void playlist_MainLoop( playlist_t *p_playlist ) ...@@ -282,8 +282,10 @@ void playlist_MainLoop( playlist_t *p_playlist )
/* Destroy object */ /* Destroy object */
vlc_object_destroy( p_input ); vlc_object_destroy( p_input );
p_playlist->i_vout_destroyed_date = 0; PL_LOCK;
p_playlist->i_sout_destroyed_date = 0;
p_playlist->gc_date = mdate();
p_playlist->b_cant_sleep = VLC_TRUE;
if( p_playlist->status.p_item->i_flags if( p_playlist->status.p_item->i_flags
& PLAYLIST_REMOVE_FLAG ) & PLAYLIST_REMOVE_FLAG )
...@@ -299,13 +301,14 @@ void playlist_MainLoop( playlist_t *p_playlist ) ...@@ -299,13 +301,14 @@ void playlist_MainLoop( playlist_t *p_playlist )
i_activity= var_GetInteger( p_playlist, "activity") ; i_activity= var_GetInteger( p_playlist, "activity") ;
var_SetInteger( p_playlist, "activity", i_activity - var_SetInteger( p_playlist, "activity", i_activity -
DEFAULT_INPUT_ACTIVITY ); DEFAULT_INPUT_ACTIVITY );
goto check_input;
return;
} }
/* This input is dying, let it do */ /* This input is dying, let it do */
else if( p_playlist->p_input->b_die ) else if( p_playlist->p_input->b_die )
{ {
PL_DEBUG( "dying input" ); PL_DEBUG( "dying input" );
msleep( 25000 ); // 25 ms
goto check_input;
} }
/* This input has finished, ask it to die ! */ /* This input has finished, ask it to die ! */
else if( p_playlist->p_input->b_error else if( p_playlist->p_input->b_error
...@@ -313,20 +316,14 @@ void playlist_MainLoop( playlist_t *p_playlist ) ...@@ -313,20 +316,14 @@ void playlist_MainLoop( playlist_t *p_playlist )
{ {
PL_DEBUG( "finished input" ); PL_DEBUG( "finished input" );
input_StopThread( p_playlist->p_input ); input_StopThread( p_playlist->p_input );
/* Select the next playlist item */ /* No need to wait here, we'll wait in the p_input->b_die case */
PL_UNLOCK goto check_input;
return;
} }
else if( p_playlist->p_input->i_state != INIT_S ) else if( p_playlist->p_input->i_state != INIT_S )
{ {
PL_UNLOCK; PL_UNLOCK;
p_playlist->i_vout_destroyed_date = ObjectGarbageCollector( p_playlist );
ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT, PL_LOCK;
p_playlist->i_vout_destroyed_date );
p_playlist->i_sout_destroyed_date =
ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT,
p_playlist->i_sout_destroyed_date );
PL_LOCK
} }
} }
else else
...@@ -374,12 +371,9 @@ void playlist_MainLoop( playlist_t *p_playlist ) ...@@ -374,12 +371,9 @@ void playlist_MainLoop( playlist_t *p_playlist )
} }
/* Collect garbage */ /* Collect garbage */
PL_UNLOCK PL_UNLOCK;
p_playlist->i_sout_destroyed_date = ObjectGarbageCollector( p_playlist );
ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT, mdate() ); PL_LOCK;
p_playlist->i_vout_destroyed_date =
ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT, mdate() );
PL_LOCK
} }
} }
PL_UNLOCK PL_UNLOCK
......
...@@ -594,10 +594,9 @@ void GoAndPreparse( playlist_t *p_playlist, int i_mode, ...@@ -594,10 +594,9 @@ void GoAndPreparse( playlist_t *p_playlist, int i_mode,
p_playlist->request.i_skip = 0; p_playlist->request.i_skip = 0;
p_playlist->request.p_item = p_toplay; p_playlist->request.p_item = p_toplay;
if( p_playlist->p_input ) if( p_playlist->p_input )
{
input_StopThread( p_playlist->p_input ); input_StopThread( p_playlist->p_input );
}
p_playlist->request.i_status = PLAYLIST_RUNNING; p_playlist->request.i_status = PLAYLIST_RUNNING;
vlc_cond_signal( &p_playlist->object_wait );
} }
if( i_mode & PLAYLIST_PREPARSE && if( i_mode & PLAYLIST_PREPARSE &&
var_CreateGetBool( p_playlist, "auto-preparse" ) ) var_CreateGetBool( p_playlist, "auto-preparse" ) )
...@@ -666,6 +665,7 @@ int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item, ...@@ -666,6 +665,7 @@ int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
p_playlist->request.b_request = VLC_TRUE; p_playlist->request.b_request = VLC_TRUE;
p_playlist->request.p_item = NULL; p_playlist->request.p_item = NULL;
msg_Info( p_playlist, "stopping playback" ); msg_Info( p_playlist, "stopping playback" );
vlc_cond_signal( &p_playlist->object_wait );
} }
b_flag = VLC_TRUE; b_flag = VLC_TRUE;
} }
......
...@@ -142,6 +142,7 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent ) ...@@ -142,6 +142,7 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent )
int playlist_ThreadDestroy( playlist_t * p_playlist ) int playlist_ThreadDestroy( playlist_t * p_playlist )
{ {
p_playlist->b_die = VLC_TRUE; p_playlist->b_die = VLC_TRUE;
playlist_Signal( p_playlist );
if( p_playlist->p_preparse ) if( p_playlist->p_preparse )
{ {
vlc_cond_signal( &p_playlist->p_preparse->object_wait ); vlc_cond_signal( &p_playlist->p_preparse->object_wait );
...@@ -175,10 +176,18 @@ static void RunControlThread ( playlist_t *p_playlist ) ...@@ -175,10 +176,18 @@ static void RunControlThread ( playlist_t *p_playlist )
HandleInteraction( p_playlist ); HandleInteraction( p_playlist );
HandlePlaylist( p_playlist ); HandlePlaylist( p_playlist );
if( p_playlist->b_cant_sleep )
{
/* 100 ms is an acceptable delay for playlist operations */ /* 100 ms is an acceptable delay for playlist operations */
msleep( INTF_IDLE_SLEEP*2 ); msleep( INTF_IDLE_SLEEP*2 );
} }
else
{
PL_LOCK;
vlc_cond_wait( &p_playlist->object_wait, &p_playlist->object_lock );
PL_UNLOCK;
}
}
EndPlaylist( p_playlist ); EndPlaylist( p_playlist );
} }
......
Markdown is supported
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