X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fplaylist%2Fengine.c;h=4a1e37e3544c2263c3ce82b46a1dd3cab48ed1a8;hb=bd8145b408e9d70d0e861cfabb6e440c95cc6ad1;hp=2aa85d18dde10f3621fdca36d3f598face43d327;hpb=575659cfe809f32a46dd584b214f541dbd8609c7;p=vlc diff --git a/src/playlist/engine.c b/src/playlist/engine.c index 2aa85d18dd..4a1e37e354 100644 --- a/src/playlist/engine.c +++ b/src/playlist/engine.c @@ -107,9 +107,11 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) return NULL; /* Create playlist and media library */ + PL_LOCK; /* playlist_NodesPairCreate will check for it */ playlist_NodesPairCreate( p_playlist, _( "Playlist" ), &p_playlist->p_local_category, &p_playlist->p_local_onelevel, false ); + PL_UNLOCK; p_playlist->p_local_category->i_flags |= PLAYLIST_RO_FLAG; p_playlist->p_local_onelevel->i_flags |= PLAYLIST_RO_FLAG; @@ -121,9 +123,11 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) if( config_GetInt( p_playlist, "media-library") ) { + PL_LOCK; /* playlist_NodesPairCreate will check for it */ playlist_NodesPairCreate( p_playlist, _( "Media Library" ), &p_playlist->p_ml_category, &p_playlist->p_ml_onelevel, false ); + PL_UNLOCK; if(!p_playlist->p_ml_category || !p_playlist->p_ml_onelevel) return NULL; @@ -221,7 +225,7 @@ static void input_selected_stream_changed( const vlc_event_t * event, void * dat /* Internals */ void playlist_release_current_input( playlist_t * p_playlist ) { - vlc_assert_locked( &(vlc_internals(p_playlist)->lock) ); + PL_ASSERT_LOCKED; if( !p_playlist->p_input ) return; @@ -244,7 +248,7 @@ void playlist_release_current_input( playlist_t * p_playlist ) void playlist_set_current_input( playlist_t * p_playlist, input_thread_t * p_input ) { - vlc_assert_locked( &(vlc_internals(p_playlist)->lock) ); + PL_ASSERT_LOCKED; playlist_release_current_input( p_playlist ); @@ -272,11 +276,58 @@ input_thread_t * playlist_CurrentInput( playlist_t * p_playlist ) return p_input; } - /** * @} */ +/** Accessor for status item and status nodes. + */ +playlist_item_t * get_current_status_item( playlist_t * p_playlist ) +{ + PL_ASSERT_LOCKED; + + return p_playlist->status.p_item; +} + +playlist_item_t * get_current_status_node( playlist_t * p_playlist ) +{ + PL_ASSERT_LOCKED; + + return p_playlist->status.p_node; +} + +void set_current_status_item( playlist_t * p_playlist, + playlist_item_t * p_item ) +{ + PL_ASSERT_LOCKED; + + if( p_playlist->status.p_item && + p_playlist->status.p_item->i_flags & PLAYLIST_REMOVE_FLAG && + p_playlist->status.p_item != p_item ) + { + PL_DEBUG( "%s was marked for deletion, deleting", + PLI_NAME( p_playlist->status.p_item ) ); + playlist_ItemDelete( p_playlist->status.p_item ); + } + p_playlist->status.p_item = p_item; +} + +void set_current_status_node( playlist_t * p_playlist, + playlist_item_t * p_node ) +{ + PL_ASSERT_LOCKED; + + if( p_playlist->status.p_node && + p_playlist->status.p_node->i_flags & PLAYLIST_REMOVE_FLAG && + p_playlist->status.p_node != p_node ) + { + PL_DEBUG( "%s was marked for deletion, deleting", + PLI_NAME( p_playlist->status.p_node ) ); + playlist_ItemDelete( p_playlist->status.p_node ); + } + p_playlist->status.p_node = p_node; +} + /** * Main loop * @@ -294,7 +345,7 @@ void playlist_MainLoop( playlist_t *p_playlist ) mdate() - p_playlist->last_rebuild_date > 30000 ) // 30 ms { ResetCurrentlyPlaying( p_playlist, var_GetBool( p_playlist, "random" ), - p_playlist->status.p_item ); + get_current_status_item( p_playlist ) ); p_playlist->last_rebuild_date = mdate(); } @@ -330,16 +381,7 @@ check_input: p_playlist->gc_date = mdate(); p_playlist->b_cant_sleep = true; - if( p_playlist->status.p_item->i_flags - & PLAYLIST_REMOVE_FLAG ) - { - PL_DEBUG( "%s was marked for deletion, deleting", - PLI_NAME( p_playlist->status.p_item ) ); - playlist_ItemDelete( p_playlist->status.p_item ); - if( p_playlist->request.p_item == p_playlist->status.p_item ) - p_playlist->request.p_item = NULL; - p_playlist->status.p_item = NULL; - } + set_current_status_item( p_playlist, NULL ); i_activity= var_GetInteger( p_playlist, "activity" ); var_SetInteger( p_playlist, "activity", i_activity - @@ -400,21 +442,15 @@ check_input: } ObjectGarbageCollector( p_playlist, true ); return; - } - playlist_PlayItem( p_playlist, p_item ); - } - else - { + } + playlist_PlayItem( p_playlist, p_item ); + } + else + { const bool b_gc_forced = p_playlist->status.i_status != PLAYLIST_STOPPED; p_playlist->status.i_status = PLAYLIST_STOPPED; - if( p_playlist->status.p_item && - p_playlist->status.p_item->i_flags & PLAYLIST_REMOVE_FLAG ) - { - PL_DEBUG( "deleting item marked for deletion" ); - playlist_ItemDelete( p_playlist->status.p_item ); - p_playlist->status.p_item = NULL; - } + set_current_status_item( p_playlist, NULL ); /* Collect garbage */ PL_UNLOCK; @@ -482,23 +518,6 @@ void playlist_LastLoop( playlist_t *p_playlist ) sout_DeleteInstance( p_sout ); #endif - if( p_playlist->status.p_node && - p_playlist->status.p_node->i_flags & PLAYLIST_REMOVE_FLAG ) - { - PL_DEBUG( "%s was marked for deletion, deleting", - PLI_NAME( p_playlist->status.p_node ) ); - playlist_ItemDelete( p_playlist->status.p_node ); - p_playlist->status.p_node = NULL; - } - if( p_playlist->status.p_item && - p_playlist->status.p_item->i_flags & PLAYLIST_REMOVE_FLAG ) - { - PL_DEBUG( "%s was marked for deletion, deleting", - PLI_NAME( p_playlist->status.p_item ) ); - playlist_ItemDelete( p_playlist->status.p_item ); - p_playlist->status.p_item = NULL; - } - /* Core should have terminated all SDs before the playlist */ /* TODO: It fails to do so when not playing anything -- Courmisch */ playlist_ServicesDiscoveryKillAll( p_playlist ); @@ -510,6 +529,13 @@ void playlist_LastLoop( playlist_t *p_playlist ) vlc_thread_join( p_playlist->p_fetcher ); PL_LOCK; + + /* Release the current node */ + set_current_status_node( p_playlist, NULL ); + + /* Release the current item */ + set_current_status_item( p_playlist, NULL ); + FOREACH_ARRAY( playlist_item_t *p_del, p_playlist->all_items ) free( p_del->pp_children ); vlc_gc_decref( p_del->p_input ); @@ -582,10 +608,15 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj ) { PL_DEBUG("meta ok for %s, need to fetch art", psz_name ); vlc_object_lock( p_playlist->p_fetcher ); - INSERT_ELEM( p_playlist->p_fetcher->pp_waiting, - p_playlist->p_fetcher->i_waiting, - p_playlist->p_fetcher->i_waiting, p_current); - vlc_object_signal_unlocked( p_playlist->p_fetcher ); + if( vlc_object_alive( p_playlist->p_fetcher ) ) + { + INSERT_ELEM( p_playlist->p_fetcher->pp_waiting, + p_playlist->p_fetcher->i_waiting, + p_playlist->p_fetcher->i_waiting, p_current); + vlc_object_signal_unlocked( p_playlist->p_fetcher ); + } + else + vlc_gc_decref( p_current ); vlc_object_unlock( p_playlist->p_fetcher ); } else @@ -610,9 +641,9 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj ) vlc_object_lock( p_obj ); } - for( int i = 0; i < p_obj->i_waiting; i++ ) + while( p_obj->i_waiting > 0 ) { - vlc_gc_decref( p_obj->pp_waiting[i] ); + vlc_gc_decref( p_obj->pp_waiting[0] ); REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 ); } @@ -698,9 +729,9 @@ void playlist_FetcherLoop( playlist_fetcher_t *p_obj ) vlc_object_lock( p_obj ); } - for( int i = 0; i < p_obj->i_waiting; i++ ) + while( p_obj->i_waiting > 0 ) { - vlc_gc_decref( p_obj->pp_waiting[i] ); + vlc_gc_decref( p_obj->pp_waiting[0] ); REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 ); }