X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fplaylist%2Fengine.c;h=4a1e37e3544c2263c3ce82b46a1dd3cab48ed1a8;hb=bd8145b408e9d70d0e861cfabb6e440c95cc6ad1;hp=f6385d01e3a83f63e0d750f3f1ef4270aa39b50a;hpb=89e10b6c29b7b18ad251b2f55da95a961d54a554;p=vlc diff --git a/src/playlist/engine.c b/src/playlist/engine.c index f6385d01e3..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; @@ -169,10 +173,15 @@ static void playlist_Destructor( vlc_object_t * p_this ) playlist_t * p_playlist = (playlist_t *)p_this; if( p_playlist->p_preparse ) + { vlc_object_release( p_playlist->p_preparse ); + } if( p_playlist->p_fetcher ) + { vlc_object_release( p_playlist->p_fetcher ); + } + msg_Dbg( p_this, "Destroyed" ); } /* Destroy remaining objects */ @@ -216,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; @@ -239,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 ); @@ -267,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 * @@ -289,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(); } @@ -325,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 - @@ -395,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,7 +523,19 @@ void playlist_LastLoop( playlist_t *p_playlist ) playlist_ServicesDiscoveryKillAll( p_playlist ); playlist_MLDump( p_playlist ); + vlc_object_kill( p_playlist->p_preparse ); + vlc_thread_join( p_playlist->p_preparse ); + vlc_object_kill( p_playlist->p_fetcher ); + 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 ); @@ -555,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 @@ -582,6 +640,13 @@ void playlist_PreparseLoop( playlist_preparse_t *p_obj ) msleep( (i_activity+1) * 1000 ); vlc_object_lock( p_obj ); } + + while( p_obj->i_waiting > 0 ) + { + vlc_gc_decref( p_obj->pp_waiting[0] ); + REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 ); + } + vlc_object_unlock( p_obj ); } @@ -663,6 +728,13 @@ void playlist_FetcherLoop( playlist_fetcher_t *p_obj ) msleep( (i_activity+1) * 1000 ); vlc_object_lock( p_obj ); } + + while( p_obj->i_waiting > 0 ) + { + vlc_gc_decref( p_obj->pp_waiting[0] ); + REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 ); + } + vlc_object_unlock( p_obj ); }