X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fplaylist%2Fthread.c;h=33f2861ec6eeb9cb2276f1a62023271e628ca15c;hb=fa81ade13492bab2a809e6c8990e211f04aecab8;hp=635af4e09b48aeb0aea3967f0c5a8077529eb4df;hpb=d3217fc729bc813a19e6743db7c5b18c7d66524c;p=vlc diff --git a/src/playlist/thread.c b/src/playlist/thread.c index 635af4e09b..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" /***************************************************************************** @@ -34,12 +38,8 @@ static void RunControlThread ( playlist_t * ); static void RunPreparse( playlist_preparse_t * ); static void RunFetcher( playlist_fetcher_t * ); - -static playlist_t * CreatePlaylist( vlc_object_t *p_parent ); -static void EndPlaylist( playlist_t * ); -static void DestroyPlaylist( playlist_t * ); - -static void DestroyInteraction( playlist_t * ); +static void PreparseDestructor( vlc_object_t * ); +static void FetcherDestructor( vlc_object_t * ); /***************************************************************************** * Main functions for the global thread @@ -48,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 @@ -56,73 +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 ); - p_playlist->p_stats_computer = NULL; - - // 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_fetcher = vlc_object_create( p_playlist, - sizeof( playlist_fetcher_t ) ); + 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_fetcher->psz_object_name = strdup( "fetcher" ); p_playlist->p_fetcher->i_waiting = 0; - p_playlist->p_fetcher->p_waiting = NULL; + 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, VLC_TRUE ) ) + VLC_THREAD_PRIORITY_LOW, true ) ) { msg_Err( p_playlist, "cannot spawn secondary preparse thread" ); - vlc_object_detach( p_playlist->p_fetcher ); - vlc_object_destroy( p_playlist->p_fetcher ); + 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; } @@ -132,84 +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 = VLC_TRUE; - playlist_Signal( p_playlist ); - if( p_playlist->p_preparse ) - { - vlc_cond_signal( &p_playlist->p_preparse->object_wait ); - free( p_playlist->p_preparse->pp_waiting ); - } - if( p_playlist->p_fetcher ) - { - vlc_cond_signal( &p_playlist->p_fetcher->object_wait ); - free( p_playlist->p_fetcher->p_waiting ); - } - - 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++; + playlist_MainLoop( p_playlist ); - if( p_playlist->p_interaction ) - intf_InteractionManage( 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_MainLoop( p_playlist ); if( p_playlist->b_cant_sleep ) { /* 100 ms is an acceptable delay for playlist operations */ + vlc_object_unlock( p_playlist ); + msleep( INTF_IDLE_SLEEP*2 ); + + vlc_object_lock( p_playlist ); } else { - PL_LOCK; - vlc_cond_wait( &p_playlist->object_wait, &p_playlist->object_lock ); - PL_UNLOCK; + vlc_object_wait( p_playlist ); } } + vlc_object_unlock( p_playlist ); - EndPlaylist( p_playlist ); -} - - -/***************************************************************************** - * Playlist-specific functions - *****************************************************************************/ -static playlist_t * CreatePlaylist( vlc_object_t *p_parent ) -{ - return playlist_Create( p_parent ); -} - -static void DestroyPlaylist( playlist_t *p_playlist ) -{ - playlist_Destroy( p_playlist ); -} - -static void EndPlaylist( playlist_t *p_playlist ) -{ playlist_LastLoop( p_playlist ); } @@ -230,15 +183,16 @@ static void RunFetcher( playlist_fetcher_t *p_obj ) playlist_FetcherLoop( p_obj ); } -/***************************************************************************** - * Interaction functions - *****************************************************************************/ -static void DestroyInteraction( playlist_t *p_playlist ) +static void PreparseDestructor( vlc_object_t * p_this ) { - if( p_playlist->p_interaction ) - { - intf_InteractionDestroy( p_playlist->p_interaction ); - fprintf( stderr, "NOW NULL ****\n" ); - p_playlist->p_interaction = NULL; - } + playlist_preparse_t * p_preparse = (playlist_preparse_t *)p_this; + free( p_preparse->pp_waiting ); + msg_Dbg( p_this, "Destroyed" ); +} + +static void FetcherDestructor( vlc_object_t * p_this ) +{ + playlist_fetcher_t * p_fetcher = (playlist_fetcher_t *)p_this; + free( p_fetcher->pp_waiting ); + msg_Dbg( p_this, "Destroyed" ); }