X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fplaylist%2Fthread.c;h=33f2861ec6eeb9cb2276f1a62023271e628ca15c;hb=07be8bb586c268720eb4deec0509f473a4d64b51;hp=5efe4231ea7f2c85c15bba53a04288777b51cc64;hpb=2d90e869b49fc72111a61ee715aa081fc92d169a;p=vlc diff --git a/src/playlist/thread.c b/src/playlist/thread.c index 5efe4231ea..33f2861ec6 100644 --- a/src/playlist/thread.c +++ b/src/playlist/thread.c @@ -1,7 +1,7 @@ /***************************************************************************** - * playlist.c : Playlist management functions + * thread.c : Playlist management functions ***************************************************************************** - * Copyright (C) 1999-2004 the VideoLAN team + * Copyright © 1999-2008 the VideoLAN team * $Id$ * * Authors: Samuel Hocevar @@ -21,11 +21,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include #include #include -#include "vlc_playlist.h" -#include "vlc_interaction.h" +#include +#include #include "playlist_internal.h" /***************************************************************************** @@ -33,17 +37,9 @@ *****************************************************************************/ static void RunControlThread ( playlist_t * ); static void RunPreparse( playlist_preparse_t * ); -static void RunSecondaryPreparse( playlist_secondary_preparse_t * ); - -static playlist_t * CreatePlaylist( vlc_object_t *p_parent ); -static void HandlePlaylist( playlist_t * ); -static void EndPlaylist( playlist_t * ); -static void DestroyPlaylist( playlist_t * ); - -static void HandleStats( playlist_t *, int ); - -static void HandleInteraction( playlist_t * ); -static void DestroyInteraction( playlist_t * ); +static void RunFetcher( playlist_fetcher_t * ); +static void PreparseDestructor( vlc_object_t * ); +static void FetcherDestructor( vlc_object_t * ); /***************************************************************************** * Main functions for the global thread @@ -52,7 +48,6 @@ static void DestroyInteraction( playlist_t * ); /** * Create the main playlist thread * Additionally to the playlist, this thread controls : - * - Interaction * - Statistics * - VLM * \param p_parent @@ -60,70 +55,71 @@ static void DestroyInteraction( playlist_t * ); */ void __playlist_ThreadCreate( vlc_object_t *p_parent ) { - playlist_t *p_playlist; - p_playlist = CreatePlaylist( p_parent ); - + playlist_t *p_playlist = playlist_Create( p_parent ); if( !p_playlist ) return; - // Stats - p_playlist->p_stats = (global_stats_t *)malloc( sizeof( global_stats_t ) ); - vlc_mutex_init( p_playlist, &p_playlist->p_stats->lock ); - - // Interaction - p_playlist->p_interaction = NULL; - // Preparse - p_playlist->p_preparse = vlc_object_create( p_playlist, - sizeof( playlist_preparse_t ) ); + static const char ppname[] = "preparser"; + p_playlist->p_preparse = + vlc_custom_create( p_playlist, sizeof( playlist_preparse_t ), + VLC_OBJECT_GENERIC, ppname ); if( !p_playlist->p_preparse ) { msg_Err( p_playlist, "unable to create preparser" ); - vlc_object_destroy( p_playlist ); + vlc_object_release( p_playlist ); return; } + p_playlist->p_preparse->psz_object_name = strdup( "preparser" ); p_playlist->p_preparse->i_waiting = 0; p_playlist->p_preparse->pp_waiting = NULL; + vlc_object_set_destructor( p_playlist->p_preparse, PreparseDestructor ); + vlc_object_attach( p_playlist->p_preparse, p_playlist ); if( vlc_thread_create( p_playlist->p_preparse, "preparser", - RunPreparse, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) ) + RunPreparse, VLC_THREAD_PRIORITY_LOW, true ) ) { msg_Err( p_playlist, "cannot spawn preparse thread" ); - vlc_object_detach( p_playlist->p_preparse ); - vlc_object_destroy( p_playlist->p_preparse ); + vlc_object_release( p_playlist->p_preparse ); return; } // Secondary Preparse - p_playlist->p_secondary_preparse = vlc_object_create( p_playlist, - sizeof( playlist_secondary_preparse_t ) ); - if( !p_playlist->p_secondary_preparse ) + static const char fname[] = "fetcher"; + p_playlist->p_fetcher = + vlc_custom_create( p_playlist, sizeof( playlist_fetcher_t ), + VLC_OBJECT_GENERIC, fname ); + if( !p_playlist->p_fetcher ) { msg_Err( p_playlist, "unable to create secondary preparser" ); - vlc_object_destroy( p_playlist ); + vlc_object_release( p_playlist ); return; } - p_playlist->p_secondary_preparse->i_waiting = 0; - p_playlist->p_secondary_preparse->p_waiting = NULL; - - vlc_object_attach( p_playlist->p_secondary_preparse, p_playlist ); - if( vlc_thread_create( p_playlist->p_secondary_preparse, - "secondary preparser", - RunSecondaryPreparse, - VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) ) + p_playlist->p_fetcher->psz_object_name = strdup( "fetcher" ); + p_playlist->p_fetcher->i_waiting = 0; + p_playlist->p_fetcher->pp_waiting = NULL; + p_playlist->p_fetcher->i_art_policy = var_CreateGetInteger( p_playlist, + "album-art" ); + + vlc_object_set_destructor( p_playlist->p_fetcher, FetcherDestructor ); + + vlc_object_attach( p_playlist->p_fetcher, p_playlist ); + if( vlc_thread_create( p_playlist->p_fetcher, + "fetcher", + RunFetcher, + VLC_THREAD_PRIORITY_LOW, true ) ) { msg_Err( p_playlist, "cannot spawn secondary preparse thread" ); - vlc_object_detach( p_playlist->p_secondary_preparse ); - vlc_object_destroy( p_playlist->p_secondary_preparse ); + vlc_object_release( p_playlist->p_fetcher ); return; } // Start the thread if( vlc_thread_create( p_playlist, "playlist", RunControlThread, - VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) ) + VLC_THREAD_PRIORITY_LOW, true ) ) { msg_Err( p_playlist, "cannot spawn playlist thread" ); - vlc_object_destroy( p_playlist ); + vlc_object_release( p_playlist ); return; } @@ -133,69 +129,40 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent ) return; } -/** - * Destroy the playlist global thread. - * - * Deinits all things controlled by the playlist global thread - * \param p_playlist the playlist thread to destroy - * \return VLC_SUCCESS or an error - */ -int playlist_ThreadDestroy( playlist_t * p_playlist ) -{ - p_playlist->b_die = 1; - - DestroyInteraction( p_playlist ); - DestroyPlaylist( p_playlist ); - - return VLC_SUCCESS; -} - /** * Run the main control thread itself */ static void RunControlThread ( playlist_t *p_playlist ) { - int i_loops = 0; - - /* Tell above that we're ready */ - vlc_thread_ready( p_playlist ); + /* Tell above that we're ready */ + vlc_thread_ready( p_playlist ); - while( !p_playlist->b_die ) + vlc_object_lock( p_playlist ); + while( vlc_object_alive( p_playlist ) ) { - i_loops++; - - HandleInteraction( p_playlist ); - HandleStats( p_playlist, i_loops ); - HandlePlaylist( p_playlist ); - - /* 100 ms is an acceptable delay for playlist operations */ - msleep( INTF_IDLE_SLEEP*2 ); - } - - EndPlaylist( p_playlist ); -} + playlist_MainLoop( p_playlist ); + /* The playlist lock has been unlocked, so we can't tell if + * someone has killed us in the meantime. Check now. */ + if( !vlc_object_alive( p_playlist ) ) + break; -/***************************************************************************** - * Playlist-specific functions - *****************************************************************************/ -static playlist_t * CreatePlaylist( vlc_object_t *p_parent ) -{ - return playlist_Create( p_parent ); -} + if( p_playlist->b_cant_sleep ) + { + /* 100 ms is an acceptable delay for playlist operations */ + vlc_object_unlock( p_playlist ); -static void DestroyPlaylist( playlist_t *p_playlist ) -{ - playlist_Destroy( p_playlist ); -} + msleep( INTF_IDLE_SLEEP*2 ); -static void HandlePlaylist( playlist_t *p_playlist ) -{ - playlist_MainLoop( p_playlist ); -} + vlc_object_lock( p_playlist ); + } + else + { + vlc_object_wait( p_playlist ); + } + } + vlc_object_unlock( p_playlist ); -static void EndPlaylist( playlist_t *p_playlist ) -{ playlist_LastLoop( p_playlist ); } @@ -204,73 +171,28 @@ static void EndPlaylist( playlist_t *p_playlist ) *****************************************************************************/ static void RunPreparse ( playlist_preparse_t *p_obj ) { - playlist_t *p_playlist = (playlist_t *)p_obj->p_parent; /* Tell above that we're ready */ vlc_thread_ready( p_obj ); - - while( !p_playlist->b_die ) - { - playlist_PreparseLoop( p_obj ); - if( p_obj->i_waiting == 0 ) - { - msleep( INTF_IDLE_SLEEP ); - } - } + playlist_PreparseLoop( p_obj ); } -static void RunSecondaryPreparse( playlist_secondary_preparse_t *p_obj ) +static void RunFetcher( playlist_fetcher_t *p_obj ) { - playlist_t *p_playlist = (playlist_t *)p_obj->p_parent; /* Tell above that we're ready */ vlc_thread_ready( p_obj ); - - while( !p_playlist->b_die ) - { - playlist_SecondaryPreparseLoop( p_obj ); - if( p_obj->i_waiting == 0 ) - { - msleep( INTF_IDLE_SLEEP ); - } - } + playlist_FetcherLoop( p_obj ); } -/***************************************************************************** - * Interaction functions - *****************************************************************************/ -static void DestroyInteraction( playlist_t *p_playlist ) -{ - if( p_playlist->p_interaction ) - { - intf_InteractionDestroy( p_playlist->p_interaction ); - fprintf( stderr, "NOW NULL ****\n" ); - p_playlist->p_interaction = NULL; - } -} - -static void HandleInteraction( playlist_t *p_playlist ) +static void PreparseDestructor( vlc_object_t * p_this ) { - if( p_playlist->p_interaction ) - { - stats_TimerStart( p_playlist, "Interaction thread", - STATS_TIMER_INTERACTION ); - intf_InteractionManage( p_playlist ); - stats_TimerStop( p_playlist, STATS_TIMER_INTERACTION ); - } + playlist_preparse_t * p_preparse = (playlist_preparse_t *)p_this; + free( p_preparse->pp_waiting ); + msg_Dbg( p_this, "Destroyed" ); } - -/***************************************************************************** - * Stats functions - *****************************************************************************/ -static void HandleStats( playlist_t *p_playlist, int i_loops ) +static void FetcherDestructor( vlc_object_t * p_this ) { - if( i_loops % 5 == 0 && p_playlist->p_stats ) - { - stats_ComputeGlobalStats( p_playlist, p_playlist->p_stats ); - if( p_playlist->p_input ) - { - stats_ComputeInputStats( p_playlist->p_input, - p_playlist->p_input->input.p_item->p_stats ); - } - } + playlist_fetcher_t * p_fetcher = (playlist_fetcher_t *)p_this; + free( p_fetcher->pp_waiting ); + msg_Dbg( p_this, "Destroyed" ); }