Commit 91d93983 authored by Clément Stenac's avatar Clément Stenac

* Provide playlist_LockFoo functions for some functions

* Fix deadlock with preparse
parent 5d3edb82
......@@ -79,10 +79,11 @@ struct playlist_item_t
/* END LEGACY FIELDS */
};
#define PLAYLIST_SAVE_FLAG 0x1 /**< Must it be saved */
#define PLAYLIST_SKIP_FLAG 0x2 /**< Must playlist skip after it ? */
#define PLAYLIST_ENA_FLAG 0x4 /**< Is it enabled ? */
#define PLAYLIST_DEL_FLAG 0x8 /**< Autodelete ? */
#define PLAYLIST_SAVE_FLAG 0x01 /**< Must it be saved */
#define PLAYLIST_SKIP_FLAG 0x02 /**< Must playlist skip after it ? */
#define PLAYLIST_ENA_FLAG 0x04 /**< Is it enabled ? */
#define PLAYLIST_DEL_FLAG 0x08 /**< Autodelete ? */
#define PLAYLIST_RO_FLAG 0x10 /**< Write-enabled ? */
/**
* playlist view
......@@ -247,6 +248,7 @@ int playlist_Destroy ( playlist_t * );
VLC_EXPORT( int, playlist_Control, ( playlist_t *, int, ... ) );
VLC_EXPORT( int, playlist_Clear, ( playlist_t * ) );
VLC_EXPORT( int, playlist_LockClear, ( playlist_t * ) );
VLC_EXPORT( int, playlist_PreparseEnqueue, (playlist_t *, input_item_t *) );
......@@ -311,17 +313,23 @@ VLC_EXPORT(int, playlist_NodeAddItem, ( playlist_t *, playlist_item_t *,int,play
/* Misc item operations (act on item+playlist) */
VLC_EXPORT( int, playlist_Delete, ( playlist_t *, int ) );
VLC_EXPORT( int, playlist_LockDelete, ( playlist_t *, int ) );
VLC_EXPORT( int, playlist_Disable, ( playlist_t *, playlist_item_t * ) );
VLC_EXPORT( int, playlist_Enable, ( playlist_t *, playlist_item_t * ) );
VLC_EXPORT( int, playlist_ItemToNode, (playlist_t *,playlist_item_t *) );
VLC_EXPORT( int, playlist_LockItemToNode, (playlist_t *,playlist_item_t *) );
VLC_EXPORT( int, playlist_Replace, (playlist_t *,playlist_item_t *, input_item_t*) );
VLC_EXPORT( int, playlist_LockReplace, (playlist_t *,playlist_item_t *, input_item_t*) );
/* Item search functions */
VLC_EXPORT( playlist_item_t *, playlist_ItemGetById, (playlist_t *, int) );
VLC_EXPORT( playlist_item_t *, playlist_LockItemGetById, (playlist_t *, int) );
VLC_EXPORT( playlist_item_t *, playlist_ItemGetByPos, (playlist_t *, int) );
VLC_EXPORT( int, playlist_GetPositionById, (playlist_t *,int ) );
VLC_EXPORT( playlist_item_t *, playlist_LockItemGetByPos, (playlist_t *, int) );
VLC_EXPORT( playlist_item_t *, playlist_ItemGetByInput, (playlist_t *,input_item_t * ) );
VLC_EXPORT( playlist_item_t *, playlist_LockItemGetByInput, (playlist_t *,input_item_t * ) );
VLC_EXPORT( int, playlist_GetPositionById, (playlist_t *,int ) );
/* Info functions */
VLC_EXPORT( char * , playlist_GetInfo, ( playlist_t * , int, const char *, const char *) );
......
......@@ -920,7 +920,7 @@ CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
CDDAMetaInfo( p_access, CDIO_INVALID_TRACK, psz_mrl );
}
p_item = playlist_ItemGetByInput( p_playlist,
p_item = playlist_LockItemGetByInput( p_playlist,
((input_thread_t *)p_access->p_parent)->input.p_item );
if( p_item == p_playlist->status.p_item && !b_single_track )
......
......@@ -228,7 +228,7 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len)
{
input_item_t *p_current = ( (input_thread_t*)p_access->p_parent)->
input.p_item;
p_item = playlist_ItemGetByInput( p_playlist, p_current );
p_item = playlist_LockItemGetByInput( p_playlist, p_current );
msg_Dbg( p_access, "not starting directory playback");
if( !p_item )
{
......
......@@ -1364,13 +1364,13 @@ VCDFixupPlayList( input_thread_t *p_input, thread_vcd_data_t *p_vcd,
psz_mrl, psz_mrl_max, psz_source, PLAYLIST_REPLACE,
p_playlist->i_index);
}
else
}
else
{
vcdinfo_itemid_t list_itemid;
list_itemid.type=VCDINFO_ITEM_TYPE_ENTRY;
playlist_Delete( p_playlist, p_playlist->i_index);
playlist_LockDelete( p_playlist, p_playlist->i_index);
for( i = 0 ; i < p_vcd->num_entries ; i++ )
{
......
......@@ -1890,7 +1890,7 @@ static void MacroDo( httpd_file_sys_t *p_args,
i_index = j;
}
playlist_Delete( p_sys->p_playlist,
playlist_LockDelete( p_sys->p_playlist,
p_items[i_index] );
msg_Dbg( p_intf, "requested playlist delete: %d",
p_items[i_index] );
......@@ -1930,7 +1930,7 @@ static void MacroDo( httpd_file_sys_t *p_args,
}
if( j == i_nb_items )
{
playlist_Delete( p_sys->p_playlist, i );
playlist_LockDelete( p_sys->p_playlist, i );
msg_Dbg( p_intf, "requested playlist delete: %d",
i );
}
......@@ -1941,10 +1941,7 @@ static void MacroDo( httpd_file_sys_t *p_args,
}
case MVLC_EMPTY:
{
while( p_sys->p_playlist->i_size > 0 )
{
playlist_Delete( p_sys->p_playlist, 0 );
}
playlist_LockClear( p_sys->p_playlist );
msg_Dbg( p_intf, "requested playlist empty" );
break;
}
......
......@@ -652,7 +652,7 @@ static vlc_bool_t FindItem( demux_t *p_demux, playlist_t *p_playlist,
{
input_item_t *p_current =
((input_thread_t*)p_demux->p_parent)->input.p_item;
*pp_item = playlist_ItemGetByInput( p_playlist, p_current );
*pp_item = playlist_LockItemGetByInput( p_playlist, p_current );
if( !*pp_item )
msg_Dbg( p_playlist, "unable to find item in playlist");
......
......@@ -338,7 +338,7 @@ static int Open( vlc_object_t * p_this )
FIND_ANYWHERE );
if( p_playlist )
{
p_item = playlist_ItemGetByInput( p_playlist,
p_item = playlist_LockItemGetByInput( p_playlist,
((input_thread_t *)p_demux->p_parent)->input.p_item );
playlist_ItemToNode( p_playlist, p_item );
......
......@@ -127,7 +127,7 @@ vlc_bool_t FindItem( demux_t *p_demux, playlist_t *p_playlist,
{
input_item_t *p_current = ( (input_thread_t*)p_demux->p_parent)->
input.p_item;
*pp_item = playlist_ItemGetByInput( p_playlist, p_current );
*pp_item = playlist_LockItemGetByInput( p_playlist, p_current );
if( !*pp_item )
{
msg_Dbg( p_playlist, "unable to find item in playlist");
......
......@@ -506,7 +506,7 @@ void GtkDeleteGListItem( gpointer data, gpointer param )
int i_cur_row = (long)data;
playlist_t * p_playlist = param;
playlist_Delete( p_playlist, i_cur_row );
playlist_LockDelete( p_playlist, i_cur_row );
}
......
......@@ -314,7 +314,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
{
playlist_Stop( p_playlist );
}
playlist_Delete( p_playlist, p_item->input.i_id );
playlist_LockDelete( p_playlist, p_item->input.i_id );
}
[self playlistUpdated];
}
......
......@@ -419,8 +419,9 @@ static int HandleKey( intf_thread_t *p_intf, int i_key )
{
int i_item = p_sys->p_playlist->i_index;
playlist_Delete( p_sys->p_playlist, p_sys->i_box_plidx );
if( i_item < p_sys->p_playlist->i_size && i_item != p_sys->p_playlist->i_index )
playlist_LockDelete( p_sys->p_playlist, p_sys->i_box_plidx );
if( i_item < p_sys->p_playlist->i_size &&
i_item != p_sys->p_playlist->i_index )
{
playlist_Goto( p_sys->p_playlist, i_item );
}
......
......@@ -873,7 +873,7 @@ void onDeletePlaylist(GtkButton *button, gpointer user_data)
*/
p_rows = g_list_reverse( p_rows );
}
for (p_node=p_rows; p_node!=NULL; p_node = p_node->next)
{
GtkTreeIter iter;
......@@ -887,7 +887,7 @@ void onDeletePlaylist(GtkButton *button, gpointer user_data)
gint item;
gtk_tree_model_get(p_model, &iter, 2, &item, -1);
playlist_Delete(p_playlist, item);
playlist_LockDelete(p_playlist, item);
}
}
}
......@@ -929,7 +929,7 @@ void onClearPlaylist(GtkButton *button, gpointer user_data)
for(item = p_playlist->i_size - 1; item >= 0 ;item-- )
{
playlist_Delete( p_playlist, item);
playlist_LockDelete( p_playlist, item);
}
vlc_object_release( p_playlist );
......
......@@ -64,9 +64,9 @@ void Playlist::delSelected()
{
if( (*it).m_selected )
{
playlist_item_t *p_item = playlist_ItemGetByPos( m_pPlaylist,
index );
playlist_Delete( m_pPlaylist, p_item->input.i_id );
playlist_item_t *p_item = playlist_LockItemGetByPos( m_pPlaylist,
index );
playlist_LockDelete( m_pPlaylist, p_item->input.i_id );
}
else
{
......
......@@ -390,7 +390,7 @@ void DialogsProvider::OnOpenDirectory( wxCommandEvent& event )
int i_id = playlist_Add( p_playlist, (const char *)path.mb_str(),
(const char *)path.mb_str(),
PLAYLIST_APPEND, PLAYLIST_END );
p_item = playlist_ItemGetById( p_playlist, i_id );
p_item = playlist_LockItemGetById( p_playlist, i_id );
if( p_item )
{
input_CreateThread( p_intf, &p_item->input );
......
......@@ -619,7 +619,7 @@ void Playlist::UpdateItem( int i )
return;
}
p_item = playlist_ItemGetById( p_playlist, i );
p_item = playlist_LockItemGetById( p_playlist, i );
wxTreeItemId item = FindItem( treectrl->GetRootItem(), p_item);
......@@ -923,7 +923,7 @@ void Playlist::DeleteItem( int item_id )
return;
}
playlist_Delete( p_playlist, item_id );
playlist_LockDelete( p_playlist, item_id );
vlc_object_release( p_playlist );
}
......@@ -1480,7 +1480,9 @@ void Playlist::OnPopupPreparse( wxMenuEvent& event )
{
if( p_popup_item->i_children == -1 )
{
wxMutexGuiLeave();
playlist_PreparseEnqueue( p_playlist, &p_popup_item->input );
wxMutexGuiEnter();
}
else
{
......
......@@ -1375,7 +1375,7 @@ static int RemoveAnnounce( services_discovery_t *p_sd,
if( p_announce->p_item )
{
playlist_Delete( p_playlist, p_announce->p_item->input.i_id );
playlist_LockDelete( p_playlist, p_announce->p_item->input.i_id );
}
for( i = 0; i< p_sd->p_sys->i_announces; i++)
......
......@@ -240,8 +240,7 @@ static void Run( intf_thread_t *p_intf )
else
{
// vlc_mutex_lock(&p_playlist->object_lock );
p_item = playlist_ItemGetByPos( p_playlist,
p_playlist->i_index );
p_item = p_playlist->status.p_item;
item = p_item->input;
if( !p_item )
{
......
......@@ -436,6 +436,15 @@ playlist_item_t * playlist_ItemGetByPos( playlist_t * p_playlist , int i_pos )
}
}
playlist_item_t *playlist_LockItemGetByPos( playlist_t *p_playlist, int i_pos )
{
playlist_item_t *p_ret;
vlc_mutex_lock( &p_playlist->object_lock );
p_ret = playlist_ItemGetByPos( p_playlist, i_pos );
vlc_mutex_unlock( &p_playlist->object_lock );
return p_ret;
}
/**
* Search an item by its id
*
......@@ -456,6 +465,15 @@ playlist_item_t * playlist_ItemGetById( playlist_t * p_playlist , int i_id )
return NULL;
}
playlist_item_t *playlist_LockItemGetById( playlist_t *p_playlist, int i_id)
{
playlist_item_t *p_ret;
vlc_mutex_lock( &p_playlist->object_lock );
p_ret = playlist_ItemGetById( p_playlist, i_id );
vlc_mutex_unlock( &p_playlist->object_lock );
return p_ret;
}
/**
* Search an item by its input_item_t
*
......@@ -482,6 +500,15 @@ playlist_item_t * playlist_ItemGetByInput( playlist_t * p_playlist ,
return NULL;
}
playlist_item_t *playlist_LockItemGetByInput( playlist_t *p_playlist,
input_item_t *p_item )
{
playlist_item_t *p_ret;
vlc_mutex_lock( &p_playlist->object_lock );
p_ret = playlist_ItemGetByInput( p_playlist, p_item );
vlc_mutex_unlock( &p_playlist->object_lock );
return p_ret;
}
/***********************************************************************
......@@ -505,8 +532,6 @@ int playlist_ItemToNode( playlist_t *p_playlist,playlist_item_t *p_item )
p_item->i_children = 0;
}
vlc_mutex_lock( &p_playlist->object_lock );
/* Remove it from the array of available items */
for( i = 0 ; i < p_playlist->i_size ; i++ )
{
......@@ -515,19 +540,27 @@ int playlist_ItemToNode( playlist_t *p_playlist,playlist_item_t *p_item )
REMOVE_ELEM( p_playlist->pp_items, p_playlist->i_size, i );
}
}
vlc_mutex_unlock( &p_playlist->object_lock );
var_SetInteger( p_playlist, "item-change", p_item->input.i_id );
return VLC_SUCCESS;
}
int playlist_LockItemToNode( playlist_t *p_playlist, playlist_item_t *p_item )
{
int i_ret;
vlc_mutex_lock( &p_playlist->object_lock );
i_ret = playlist_ItemToNode( p_playlist, p_item );
vlc_mutex_unlock( &p_playlist->object_lock );
return i_ret;
}
/**
* Replaces an item with another one
* This function must be entered without the playlist lock
*
* \see playlist_Replace
*/
int playlist_LockAndReplace( playlist_t *p_playlist,
int playlist_LockReplace( playlist_t *p_playlist,
playlist_item_t *p_olditem,
input_item_t *p_new )
{
......@@ -604,12 +637,12 @@ int playlist_Delete( playlist_t * p_playlist, int i_id )
/* Check if it is the current item */
if( p_playlist->status.p_item == p_item )
{
playlist_Control( p_playlist, PLAYLIST_STOP );
/* Hack we don't call playlist_Control for lock reasons */
p_playlist->status.i_status = PLAYLIST_STOPPED;
p_playlist->request.b_request = VLC_TRUE;
p_playlist->status.p_item = NULL;
}
vlc_mutex_lock( &p_playlist->object_lock );
msg_Dbg( p_playlist, "deleting playlist item `%s'",
p_item->input.psz_name );
......@@ -628,11 +661,18 @@ int playlist_Delete( playlist_t * p_playlist, int i_id )
playlist_ItemDelete( p_item );
vlc_mutex_unlock( &p_playlist->object_lock );
return VLC_SUCCESS;
}
int playlist_LockDelete( playlist_t * p_playlist, int i_id )
{
int i_ret;
vlc_mutex_lock( &p_playlist->object_lock );
i_ret = playlist_Delete( p_playlist, i_id );
vlc_mutex_unlock( &p_playlist->object_lock );
return i_ret;
}
/**
* Clear all playlist items
*
......@@ -654,6 +694,15 @@ int playlist_Clear( playlist_t * p_playlist )
return VLC_SUCCESS;
}
int playlist_LockClear( playlist_t *p_playlist )
{
int i_ret;
vlc_mutex_lock( &p_playlist->object_lock );
playlist_Clear( p_playlist );
vlc_mutex_unlock( &p_playlist->object_lock );
return i_ret;
}
/**
* Disables a playlist item
......
......@@ -127,6 +127,7 @@ playlist_t * __playlist_Create ( vlc_object_t *p_parent )
p_playlist->p_general = playlist_NodeCreate( p_playlist, VIEW_CATEGORY,
_( "General" ), p_view->p_root );
p_playlist->p_general->i_flags |= PLAYLIST_RO_FLAG;
/* Set startup status
* We set to simple view on startup for interfaces that don't do
......@@ -572,10 +573,8 @@ static void RunThread ( playlist_t *p_playlist )
{
if( p_autodelete_item )
{
vlc_mutex_unlock( &p_playlist->object_lock );
playlist_Delete( p_playlist,
p_autodelete_item->input.i_id );
vlc_mutex_lock( &p_playlist->object_lock );
p_autodelete_item = NULL;
}
p_playlist->status.i_status = PLAYLIST_STOPPED;
......@@ -587,9 +586,7 @@ static void RunThread ( playlist_t *p_playlist )
if( p_autodelete_item )
{
vlc_mutex_unlock( &p_playlist->object_lock );
playlist_Delete( p_playlist, p_autodelete_item->input.i_id );
vlc_mutex_lock( &p_playlist->object_lock );
p_autodelete_item = NULL;
}
}
......@@ -770,7 +767,7 @@ static playlist_item_t * NextItem( playlist_t *p_playlist )
return NULL;
}
if( !p_playlist->request.b_request && p_playlist->status.p_item &&
if( !p_playlist->request.b_request && p_playlist->status.p_item &&
!(p_playlist->status.p_item->i_flags & PLAYLIST_SKIP_FLAG) )
{
msg_Dbg( p_playlist, "no-skip mode, stopping") ;
......
......@@ -86,6 +86,8 @@ playlist_view_t * playlist_ViewCreate( playlist_t *p_playlist, int i_id,
/**
* Creates a new view and add it to the list
*
* This function must be entered without the playlist lock
*
* \param p_playlist a playlist object
* \param i_id the view identifier
* \return VLC_SUCCESS or an error
......@@ -113,6 +115,8 @@ int playlist_ViewInsert( playlist_t *p_playlist, int i_id, char *psz_name )
/**
* Deletes a view
*
* This function must be entered wit the playlist lock
*
* \param p_view the view to delete
* \return nothing
*/
......@@ -122,7 +126,6 @@ int playlist_ViewDelete( playlist_t *p_playlist,playlist_view_t *p_view )
return VLC_SUCCESS;
}
/**
* Dumps the content of a view
*
......@@ -366,15 +369,22 @@ int playlist_NodeDelete( playlist_t *p_playlist, playlist_item_t *p_root,
playlist_Delete( p_playlist, p_root->pp_children[i]->input.i_id );
}
}
var_SetInteger( p_playlist, "item-deleted", p_root->input.i_id );
/* Delete the node */
for( i = 0 ; i< p_root->i_parents; i++ )
if( p_root->i_flags & PLAYLIST_RO_FLAG )
{
playlist_NodeRemoveItem( p_playlist, p_root,
p_root->pp_parents[i]->p_parent );
msg_Dbg( p_playlist, "unable to remove node, write-protected" );
}
playlist_ItemDelete( p_root );
return VLC_SUCCESS;
else
{
for( i = 0 ; i< p_root->i_parents; i++ )
{
playlist_NodeRemoveItem( p_playlist, p_root,
p_root->pp_parents[i]->p_parent );
}
var_SetInteger( p_playlist, "item-deleted", p_root->input.i_id );
playlist_ItemDelete( p_root );
}
return VLC_SUCCESS;
}
......
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