From 19f1b2ee4608ff6c6935d0f8c7289bcebb0e7f7e Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Mon, 22 Dec 2008 18:22:09 +0100 Subject: [PATCH] Split creation/destruction and activation/deactivation of playlist. It will allow to fix playlist<->interface dependency problems. --- src/libvlc.c | 34 +++++++++++++++++++------------- src/playlist/engine.c | 12 +++++------ src/playlist/playlist_internal.h | 13 ++++++------ src/playlist/thread.c | 32 ++++++++++++++++++++---------- 4 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/libvlc.c b/src/libvlc.c index b9af56d2d0..3fd83f7407 100644 --- a/src/libvlc.c +++ b/src/libvlc.c @@ -818,8 +818,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, priv->p_interaction = interaction_Init( p_libvlc ); /* Initialize playlist and get commandline files */ - playlist_ThreadCreate( p_libvlc ); - if( !priv->p_playlist ) + p_playlist = playlist_Create( VLC_OBJECT(p_libvlc) ); + if( !p_playlist ) { msg_Err( p_libvlc, "playlist initialization failed" ); if( priv->p_memcpy_module != NULL ) @@ -829,7 +829,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, module_EndBank( p_libvlc ); return VLC_EGENERIC; } - p_playlist = priv->p_playlist; + playlist_Activate( p_playlist ); + vlc_object_attach( p_playlist, p_libvlc ); psz_modules = config_GetPsz( p_playlist, "services-discovery" ); if( psz_modules && *psz_modules ) @@ -1020,11 +1021,20 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, */ int libvlc_InternalCleanup( libvlc_int_t *p_libvlc ) { - intf_thread_t * p_intf = NULL; - libvlc_priv_t *priv = libvlc_priv (p_libvlc); + libvlc_priv_t *priv = libvlc_priv (p_libvlc); + playlist_t *p_playlist = priv->p_playlist; + + /* Deactivate the playlist */ + msg_Dbg( p_libvlc, "deactivating the playlist" ); + playlist_Deactivate( p_playlist ); + + /* Remove all services discovery */ + msg_Dbg( p_libvlc, "removing all services discovery tasks" ); + playlist_ServicesDiscoveryKillAll( p_playlist ); /* Ask the interfaces to stop and destroy them */ msg_Dbg( p_libvlc, "removing all interfaces" ); + intf_thread_t *p_intf; while( (p_intf = vlc_object_find( p_libvlc, VLC_OBJECT_INTF, FIND_CHILD )) ) { intf_StopThread( p_intf ); @@ -1041,17 +1051,13 @@ int libvlc_InternalCleanup( libvlc_int_t *p_libvlc ) } #endif - playlist_t *p_playlist = priv->p_playlist; - /* Remove all services discovery */ - msg_Dbg( p_libvlc, "removing all services discovery tasks" ); - playlist_ServicesDiscoveryKillAll( p_playlist ); - /* Free playlist */ /* Any thread still running must not assume pl_Hold() succeeds. */ msg_Dbg( p_libvlc, "removing playlist" ); - priv->p_playlist = NULL; - vlc_object_kill( p_playlist ); /* <-- memory barrier for pl_Hold() */ - vlc_thread_join( p_playlist ); + + libvlc_priv(p_playlist->p_libvlc)->p_playlist = NULL; + barrier(); /* FIXME is that correct ? */ + vlc_object_release( p_playlist ); /* Free interaction */ @@ -1087,7 +1093,7 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc ) if( !p_libvlc ) return VLC_EGENERIC; - libvlc_priv_t *priv = libvlc_priv (p_libvlc); + libvlc_priv_t *priv = libvlc_priv( p_libvlc ); #ifndef WIN32 char* psz_pidfile = NULL; diff --git a/src/playlist/engine.c b/src/playlist/engine.c index 5a8e377152..d3e8ffa6bf 100644 --- a/src/playlist/engine.c +++ b/src/playlist/engine.c @@ -177,13 +177,10 @@ static void playlist_Destructor( vlc_object_t * p_this ) playlist_t *p_playlist = (playlist_t *)p_this; playlist_private_t *p_sys = pl_priv(p_playlist); - if( p_sys->p_preparser ) - playlist_preparser_Delete( p_sys->p_preparser ); + assert( !p_sys->p_preparser ); + assert( !p_sys->p_fetcher ); - if( p_sys->p_fetcher ) - playlist_fetcher_Delete( p_sys->p_fetcher ); - - msg_Dbg( p_this, "Destroyed" ); + msg_Err( p_this, "Destroyed" ); } /* Destroy remaining objects */ @@ -572,6 +569,9 @@ static void VariablesInit( playlist_t *p_playlist ) var_Create( p_playlist, "loop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_AddCallback( p_playlist, "random", RandomCallback, NULL ); + + /* */ + var_Create( p_playlist, "album-art", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); } int playlist_CurrentId( playlist_t * p_playlist ) diff --git a/src/playlist/playlist_internal.h b/src/playlist/playlist_internal.h index 224b1bd7c2..a16f575c68 100644 --- a/src/playlist/playlist_internal.h +++ b/src/playlist/playlist_internal.h @@ -99,16 +99,17 @@ typedef struct playlist_private_t * Prototypes *****************************************************************************/ -/* Global thread */ -#define playlist_ThreadCreate(a) __playlist_ThreadCreate(VLC_OBJECT(a)) -void __playlist_ThreadCreate ( vlc_object_t * ); +/* Creation/Deletion */ +playlist_t *playlist_Create( vlc_object_t * ); + +/* */ +void playlist_Activate( playlist_t * ); +void playlist_Deactivate( playlist_t * ); +/* */ playlist_item_t *playlist_ItemNewFromInput( playlist_t *p_playlist, input_item_t *p_input ); -/* Creation/Deletion */ -playlist_t *playlist_Create ( vlc_object_t * ); - /* Engine */ void playlist_MainLoop( playlist_t * ); void playlist_LastLoop( playlist_t * ); diff --git a/src/playlist/thread.c b/src/playlist/thread.c index 4c7e9a1bf3..8792bc1816 100644 --- a/src/playlist/thread.c +++ b/src/playlist/thread.c @@ -42,19 +42,15 @@ static void* RunControlThread ( vlc_object_t * ); *****************************************************************************/ /** - * Create the main playlist thread + * Create the main playlist threads. * Additionally to the playlist, this thread controls : * - Statistics * - VLM * \param p_parent * \return an object with a started thread */ -void __playlist_ThreadCreate( vlc_object_t *p_parent ) +void playlist_Activate( playlist_t *p_playlist ) { - playlist_t *p_playlist = playlist_Create( p_parent ); - if( !p_playlist ) - return; - /* */ playlist_private_t *p_sys = pl_priv(p_playlist); @@ -73,12 +69,28 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent ) VLC_THREAD_PRIORITY_LOW, false ) ) { msg_Err( p_playlist, "cannot spawn playlist thread" ); - vlc_object_release( p_playlist ); - return; } + msg_Err( p_playlist, "Activated" ); +} + +void playlist_Deactivate( playlist_t *p_playlist ) +{ + /* */ + playlist_private_t *p_sys = pl_priv(p_playlist); + + msg_Err( p_playlist, "Deactivate" ); + vlc_object_kill( p_playlist ); + vlc_thread_join( p_playlist ); + + if( p_sys->p_preparser ) + playlist_preparser_Delete( p_sys->p_preparser ); + if( p_sys->p_fetcher ) + playlist_fetcher_Delete( p_sys->p_fetcher ); - /* The object has been initialized, now attach it */ - vlc_object_attach( p_playlist, p_parent ); + /* The NULL are there only to assert in playlist destructor */ + p_sys->p_preparser = NULL; + p_sys->p_fetcher = NULL; + msg_Err( p_playlist, "Deactivated" ); } /** -- 2.39.2