Commit 0e86a35f authored by Rafaël Carré's avatar Rafaël Carré

Do not use playlist_*AddInput() when the playlist has already been destroyed...

Do not use playlist_*AddInput() when the playlist has already been destroyed and is dying (fix a crash when exiting while directory access is still reading) Try to return early if one of those function fail, because it either mean we don't have anymore memory available (I'm still looking for infinite Turing machines), or we are exiting (the playlist is dying). Use object / thread helpers for simplicity
parent c13a0a1d
......@@ -490,12 +490,15 @@ static int GetTracks( access_t *p_access,
}
}
#endif
playlist_BothAddInput( p_playlist, p_input_item, p_item_in_category,
int i_ret = playlist_BothAddInput( p_playlist, p_input_item,
p_item_in_category,
PLAYLIST_APPEND, PLAYLIST_END, NULL, NULL,
VLC_FALSE );
vlc_gc_decref( p_input_item );
free( psz_uri ); free( psz_opt ); free( psz_name );
free( psz_first ); free( psz_last );
if( i_ret != VLC_SUCCESS )
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
......
......@@ -530,13 +530,15 @@ static int ReadDir( playlist_t *p_playlist, const char *psz_name,
{
if( p_current_input )
input_ItemCopyOptions( p_current_input, p_input );
playlist_BothAddInput( p_playlist, p_input,
int i_ret = playlist_BothAddInput( p_playlist, p_input,
p_parent_category,
PLAYLIST_APPEND|PLAYLIST_PREPARSE|
PLAYLIST_NO_REBUILD,
PLAYLIST_END, NULL, NULL,
VLC_FALSE );
vlc_gc_decref( p_input );
if( i_ret != VLC_SUCCESS )
return VLC_EGENERIC;
}
}
}
......
......@@ -345,11 +345,15 @@ static void MacroDo( httpd_file_sys_t *p_args,
}
else
{
playlist_AddInput( p_sys->p_playlist, p_input,
int i_ret = playlist_AddInput( p_sys->p_playlist,
p_input,
PLAYLIST_APPEND, PLAYLIST_END, VLC_TRUE,
VLC_FALSE);
vlc_gc_decref( p_input );
msg_Dbg( p_intf, "requested mrl add: %s", mrl );
if( i_ret == VLC_SUCCESS )
msg_Dbg( p_intf, "requested mrl add: %s", mrl );
else
msg_Warn( p_intf, "adding mrl %s failed", mrl );
}
free( psz_uri );
......
......@@ -848,7 +848,10 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t *vars,
PLAYLIST_APPEND, PLAYLIST_END, VLC_TRUE,
VLC_FALSE);
vlc_gc_decref( p_input );
msg_Dbg( p_intf, "requested mrl add: %s", mrl );
if( i_ret == VLC_SUCCESS )
msg_Dbg( p_intf, "requested mrl add: %s", mrl );
else
msg_Warn( p_intf, "adding mrl %s failed", mrl );
}
free( psz_uri );
E_(SSPushN)( st, i_ret );
......
......@@ -1423,9 +1423,12 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
if( p_item )
{
msg_rc( "Trying to add %s to playlist.", newval.psz_string );
playlist_AddInput( p_playlist, p_item,
if( playlist_AddInput( p_playlist, p_item,
PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END, VLC_TRUE,
VLC_FALSE );
VLC_FALSE ) != VLC_SUCCESS );
{
return VLC_EGENERIC;
}
}
}
else if( !strcmp( psz_cmd, "enqueue" ) &&
......@@ -1436,9 +1439,12 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
if( p_item )
{
msg_rc( "trying to enqueue %s to playlist", newval.psz_string );
playlist_AddInput( p_playlist, p_item,
if( playlist_AddInput( p_playlist, p_item,
PLAYLIST_APPEND, PLAYLIST_END, VLC_TRUE,
VLC_FALSE);
VLC_FALSE ) != VLC_SUCCESS )
{
return VLC_EGENERIC;
}
}
}
else if( !strcmp( psz_cmd, "playlist" ) )
......@@ -1465,7 +1471,7 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
msg_rc( STATUS_CHANGE "( audio volume: %d )",
config_GetInt( p_intf, "volume" ));
vlc_mutex_lock( &p_playlist->object_lock );
PL_LOCK;
switch( p_playlist->status.i_status )
{
case PLAYLIST_STOPPED:
......@@ -1481,7 +1487,7 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
msg_rc( STATUS_CHANGE "( state unknown )" );
break;
}
vlc_mutex_unlock( &p_playlist->object_lock );
PL_UNLOCK;
}
}
......
......@@ -415,7 +415,7 @@ static int Open( vlc_object_t * p_this )
asprintf( &psz_absolute, "%s://%s%s",
p_demux->psz_access, psz_path, psz_ref );
if( psz_ref ) free( psz_ref );
free( psz_ref );
psz_ref = psz_absolute;
free( psz_path );
}
......@@ -426,6 +426,7 @@ static int Open( vlc_object_t * p_this )
p_input = input_ItemNewExt( p_playlist, psz_ref, NULL,
0, NULL, -1 );
input_ItemCopyOptions( p_current->p_input, p_input );
/* FIXME: playlist_BothAddInput() can fail */
playlist_BothAddInput( p_playlist, p_input,
p_item_in_category,
PLAYLIST_APPEND, PLAYLIST_END,
......
......@@ -57,6 +57,7 @@
[o_urlString fileSystemRepresentation],
[[[NSFileManager defaultManager]
displayNameAtPath: o_urlString] UTF8String] );
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( p_playlist, p_input, PLAYLIST_INSERT,
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
......
......@@ -1002,6 +1002,7 @@
}
/* Add the item */
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( p_playlist, p_input, PLAYLIST_INSERT,
i_position == -1 ? PLAYLIST_END : i_position + i_item, VLC_TRUE,
VLC_FALSE );
......@@ -1042,6 +1043,7 @@
}
/* Add the item */
/* FIXME: playlist_NodeAddInput() can fail */
playlist_NodeAddInput( p_playlist, p_input, p_node,
PLAYLIST_INSERT,
i_position == -1 ?
......
......@@ -1292,6 +1292,7 @@ static VLCWizard *_o_sharedInstance = nil;
@"ttl=%@", [o_userSelections objectForKey:@"ttl"]]
UTF8String] );
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( p_playlist, p_input, PLAYLIST_STOP,
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
......
......@@ -316,18 +316,10 @@ void OpenDialog::finish( bool b_enqueue = false )
}
/* Switch between enqueuing and starting the item */
if( b_start )
{
playlist_AddInput( THEPL, p_input,
PLAYLIST_APPEND | PLAYLIST_GO,
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
}
else
{
playlist_AddInput( THEPL, p_input,
PLAYLIST_APPEND | PLAYLIST_PREPARSE,
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
}
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( THEPL, p_input,
PLAYLIST_APPEND | ( b_start ? PLAYLIST_GO : PLAYLIST_PREPARSE ),
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
}
}
else
......
......@@ -351,6 +351,7 @@ static void openDirectory( intf_thread_t *p_intf, bool pl, bool go )
qtu( "directory://" + dir ), NULL,
0, NULL, -1 );
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( THEPL, p_input,
go ? ( PLAYLIST_APPEND | PLAYLIST_GO ) : PLAYLIST_APPEND,
PLAYLIST_END, pl, VLC_FALSE );
......
......@@ -1205,18 +1205,10 @@ void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
}
}
if( b_start )
{
playlist_AddInput( p_playlist, p_input,
PLAYLIST_APPEND | PLAYLIST_GO,
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
}
else
{
playlist_AddInput( p_playlist, p_input,
PLAYLIST_APPEND|PLAYLIST_PREPARSE,
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
}
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( p_playlist, p_input,
PLAYLIST_APPEND | ( b_start ? PLAYLIST_GO : PLAYLIST_PREPARSE ),
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
}
vlc_object_release( p_playlist );
......
......@@ -1289,9 +1289,11 @@ bool PlaylistFileDropTarget::OnDropFiles( wxCoord x, wxCoord y,
char *psz_utf8 = wxDnDFromLocale( filenames[i] );
input_item_t *p_input = input_ItemNew( p->p_playlist,
psz_utf8, psz_utf8 );
playlist_NodeAddInput( p->p_playlist, p_input,
p_dest, PLAYLIST_PREPARSE, i_pos, VLC_FALSE );
int i_ret = ( playlist_NodeAddInput( p->p_playlist, p_input, p_dest,
PLAYLIST_PREPARSE, i_pos, VLC_FALSE ) != VLC_SUCCESS );
wxDnDLocaleFree( psz_utf8 );
if( i_ret != VLC_SUCCESS )
return FALSE;
}
/* FIXME: having this Rebuild() is dirty */
......
......@@ -1632,6 +1632,7 @@ void WizardDialog::Run()
snprintf( psz_ttl, 20, "ttl=%i",i_ttl );
input_ItemAddOption( p_input, psz_ttl );
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( p_playlist, p_input,
PLAYLIST_GO, PLAYLIST_END, VLC_TRUE, VLC_FALSE );
vlc_object_release(p_playlist);
......
......@@ -748,14 +748,12 @@ int __vlclua_playlist_add_internal( vlc_object_t *p_this, lua_State *L,
/* Append item to playlist */
if( p_parent ) /* Add to node */
input_ItemAddSubItem( p_parent, p_input );
else if( b_play ) /* Play */
else /* Play or Enqueue (preparse) */
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( p_playlist, p_input,
PLAYLIST_APPEND | PLAYLIST_GO,
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
else /* Enqueue */
playlist_AddInput( p_playlist, p_input,
PLAYLIST_APPEND | PLAYLIST_PREPARSE,
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
PLAYLIST_APPEND |
( b_play ? PLAYLIST_GO : PLAYLIST_PREPARSE ),
PLAYLIST_END, VLC_TRUE, VLC_FALSE );
i_count ++; /* increment counter */
vlc_gc_decref( p_input );
while( i_options > 0 )
......
......@@ -217,6 +217,7 @@ void UPnPHandler::AddContent( playlist_item_t *p_parent, ContentNode *node )
{
ItemNode *iNode = (ItemNode *)node;
input_item_t *p_input = input_ItemNew( p_sd, iNode->getResource(), title );
/* FIXME: playlist_AddInput() can fail */
playlist_BothAddInput( p_playlist, p_input, p_parent,
PLAYLIST_APPEND, PLAYLIST_END, NULL, NULL,
VLC_FALSE );
......
......@@ -871,6 +871,7 @@ void MediaServer::_buildPlaylist( Container* parent )
item->getResource(),
item->getTitle() );
int i_cat;
/* FIXME: playlist_AddInput() can fail */
playlist_BothAddInput( p_playlist, p_input, parentNode,
PLAYLIST_APPEND, PLAYLIST_END, &i_cat, NULL,
VLC_FALSE );
......
......@@ -500,20 +500,19 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj )
while( !p_playlist->b_die )
{
vlc_mutex_lock( &p_obj->object_lock );
vlc_object_lock( p_obj );
while( p_obj->i_waiting == 0 )
{
vlc_cond_wait( &p_obj->object_wait, &p_obj->object_lock );
if( p_playlist->b_die )
if( vlc_object_wait( p_obj ) || p_playlist->b_die )
{
vlc_mutex_unlock( &p_obj->object_lock );
vlc_object_unlock( p_obj );
return;
}
}
p_current = p_obj->pp_waiting[0];
REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 );
vlc_mutex_unlock( &p_obj->object_lock );
vlc_object_unlock( p_obj );
PL_LOCK;
if( p_current )
......@@ -548,12 +547,12 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj )
PL_DEBUG( "need to fetch meta for %s", p_current->psz_name );
p.p_item = p_current;
p.b_fetch_art = VLC_FALSE;
vlc_mutex_lock( &p_playlist->p_fetcher->object_lock );
vlc_object_lock( p_playlist->p_fetcher );
INSERT_ELEM( p_playlist->p_fetcher->p_waiting,
p_playlist->p_fetcher->i_waiting,
p_playlist->p_fetcher->i_waiting, p);
vlc_cond_signal( &p_playlist->p_fetcher->object_wait );
vlc_mutex_unlock( &p_playlist->p_fetcher->object_lock );
vlc_object_signal_unlocked( p_playlist->p_fetcher );
vlc_object_unlock( p_playlist->p_fetcher );
}
/* We already have all needed meta, but we need art right now */
else if( p_playlist->p_fetcher->i_art_policy == ALBUM_ART_ALL &&
......@@ -563,12 +562,12 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj )
PL_DEBUG("meta ok for %s, need to fetch art", psz_name );
p.p_item = p_current;
p.b_fetch_art = VLC_TRUE;
vlc_mutex_lock( &p_playlist->p_fetcher->object_lock );
vlc_object_lock( p_playlist->p_fetcher );
INSERT_ELEM( p_playlist->p_fetcher->p_waiting,
p_playlist->p_fetcher->i_waiting,
p_playlist->p_fetcher->i_waiting, p);
vlc_cond_signal( &p_playlist->p_fetcher->object_wait );
vlc_mutex_unlock( &p_playlist->p_fetcher->object_lock );
vlc_object_signal_unlocked( p_playlist->p_fetcher );
vlc_object_unlock( p_playlist->p_fetcher );
}
else
{
......@@ -583,10 +582,10 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj )
else
PL_UNLOCK;
vlc_mutex_lock( &p_obj->object_lock );
vlc_object_lock( p_obj );
i_activity = var_GetInteger( p_playlist, "activity" );
if( i_activity < 0 ) i_activity = 0;
vlc_mutex_unlock( &p_obj->object_lock );
vlc_object_unlock( p_obj );
/* Sleep at least 1ms */
msleep( (i_activity+1) * 1000 );
}
......
......@@ -90,11 +90,12 @@ static void input_item_subitem_added( const vlc_event_t * p_event,
p_item_in_category->p_input->i_type = ITEM_TYPE_PLAYLIST;
}
playlist_BothAddInput( p_playlist, p_child, p_item_in_category,
int i_ret = playlist_BothAddInput( p_playlist, p_child,
p_item_in_category,
PLAYLIST_APPEND | PLAYLIST_SPREPARSE , PLAYLIST_END,
NULL, NULL, VLC_TRUE );
if( b_play )
if( i_ret == VLC_SUCCESS && b_play )
{
playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
VLC_TRUE, p_item_in_category, NULL );
......@@ -368,14 +369,14 @@ int playlist_AddExt( playlist_t *p_playlist, const char * psz_uri,
* regardless of its size
* \param b_playlist TRUE for playlist, FALSE for media library
* \param b_locked TRUE if the playlist is locked
* \return VLC_SUCCESS or VLC_ENOMEM
* \return VLC_SUCCESS or VLC_ENOMEM or VLC_EGENERIC
*/
int playlist_AddInput( playlist_t* p_playlist, input_item_t *p_input,
int i_mode, int i_pos, vlc_bool_t b_playlist,
vlc_bool_t b_locked )
{
playlist_item_t *p_item_cat, *p_item_one;
if( p_playlist->b_die ) return VLC_EGENERIC;
if( !p_playlist->b_doing_ml )
PL_DEBUG( "adding item `%s' ( %s )", p_input->psz_name,
p_input->psz_uri );
......@@ -417,7 +418,7 @@ int playlist_AddInput( playlist_t* p_playlist, input_item_t *p_input,
* \param i_cat id of the items category
* \param i_one id of the item onelevel category
* \param b_locked TRUE if the playlist is locked
* \return VLC_SUCCESS or VLC_ENOMEM
* \return VLC_SUCCESS if success, VLC_EGENERIC if fail, VLC_ENOMEM if OOM
*/
int playlist_BothAddInput( playlist_t *p_playlist,
input_item_t *p_input,
......@@ -428,6 +429,7 @@ int playlist_BothAddInput( playlist_t *p_playlist,
playlist_item_t *p_item_cat, *p_item_one, *p_up;
int i_top;
assert( p_input );
if( p_playlist->b_die ) return VLC_EGENERIC;
if( !b_locked ) PL_LOCK;
/* Add to category */
......@@ -488,6 +490,8 @@ playlist_item_t * playlist_NodeAddInput( playlist_t *p_playlist,
assert( p_input );
assert( p_parent && p_parent->i_children != -1 );
if( p_playlist->b_die )
return NULL;
if( !b_locked ) PL_LOCK;
p_item = playlist_ItemNewFromInput( p_playlist, p_input );
......
......@@ -101,6 +101,8 @@ static void input_item_subitem_added( const vlc_event_t * p_event,
playlist_t *p_playlist = user_data;
input_item_t *p_item = p_event->u.input_item_subitem_added.p_new_child;
/* playlist_AddInput() can fail, but we have no way to report that ..
* Any way when it has failed, either the playlist is dying, either OOM */
playlist_AddInput( p_playlist, p_item, PLAYLIST_APPEND, PLAYLIST_END,
VLC_FALSE, VLC_FALSE );
}
......
......@@ -234,8 +234,11 @@ static void playlist_sd_item_added( const vlc_event_t * p_event, void * user_dat
p_new_item = playlist_NodeAddInput( p_parent->p_playlist, p_input, p_parent,
PLAYLIST_APPEND, PLAYLIST_END, VLC_FALSE );
p_new_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
p_new_item->i_flags &= ~PLAYLIST_SAVE_FLAG;
if( p_new_item )
{
p_new_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
p_new_item->i_flags &= ~PLAYLIST_SAVE_FLAG;
}
}
/* A new item has been removed from a certain sd */
......
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