From dbdd540a2e2aefb8f572d199ddd1b850f9d97f11 Mon Sep 17 00:00:00 2001 From: Pierre d'Herbemont Date: Sun, 23 Mar 2008 00:55:15 +0100 Subject: [PATCH] interaction: Keep a libvlc's global interaction object reference around, and properly release it when done. --- include/main.h | 2 ++ src/interface/interaction.c | 59 +++++++++++++++++++++---------------- src/libvlc-common.c | 9 ++++++ 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/include/main.h b/include/main.h index 7527d9e6f9..596de281a3 100644 --- a/include/main.h +++ b/include/main.h @@ -45,6 +45,8 @@ struct libvlc_int_t playlist_t *p_playlist; ///< playlist object + vlc_object_t *p_interaction; ///< interface interaction object + /* Messages */ msg_bank_t msg_bank; ///< The message bank int i_verbose; ///< info messages diff --git a/src/interface/interaction.c b/src/interface/interaction.c index 7763186ea9..fab49f7f27 100644 --- a/src/interface/interaction.c +++ b/src/interface/interaction.c @@ -38,15 +38,16 @@ #include #include +#include "interface.h" /***************************************************************************** * Local prototypes *****************************************************************************/ -static interaction_t * InteractionInit( libvlc_int_t * ); static interaction_t * InteractionGet( vlc_object_t * ); static void InteractionSearchInterface( interaction_t * ); static void InteractionLoop( vlc_object_t * ); static void InteractionManage( interaction_t * ); +static void interaction_Destructor( vlc_object_t *p_interaction ); static interaction_dialog_t *DialogGetById( interaction_t* , int ); static void DialogDestroy( interaction_dialog_t * ); @@ -346,27 +347,20 @@ void __intf_UserHide( vlc_object_t *p_this, int i_id ) vlc_object_release( p_interaction ); } -/********************************************************************** - * The following functions are local - **********************************************************************/ - -/* Get the interaction object. Create it if needed */ -static interaction_t * InteractionGet( vlc_object_t *p_this ) +/** + * Create the initial interaction object + * (should only be used in libvlc_InternalInit, LibVLC private) + * + * \return a vlc_object_t that should be freed when done. + */ +vlc_object_t * interaction_Init( libvlc_int_t *p_libvlc ) { - interaction_t *p_interaction = - vlc_object_find( p_this, VLC_OBJECT_INTERACTION, FIND_ANYWHERE ); + interaction_t *p_interaction; - if( !p_interaction ) - p_interaction = InteractionInit( p_this->p_libvlc ); - - return p_interaction; -} - -/* Create the interaction object in the given playlist object */ -static interaction_t * InteractionInit( libvlc_int_t *p_libvlc ) -{ - interaction_t *p_interaction = - vlc_object_create( p_libvlc, VLC_OBJECT_INTERACTION ); + /* Make sure we haven't yet created an interaction object */ + assert( vlc_object_find( p_libvlc, VLC_OBJECT_INTERACTION, FIND_ANYWHERE ) == NULL ); + + p_interaction = vlc_object_create( p_libvlc, VLC_OBJECT_INTERACTION ); if( p_interaction ) { @@ -387,13 +381,29 @@ static interaction_t * InteractionInit( libvlc_int_t *p_libvlc ) vlc_object_release( p_interaction ); p_interaction = NULL; } - else - vlc_object_yield( p_interaction ); } + + vlc_object_set_destructor( p_interaction, interaction_Destructor ); - return p_interaction; + return VLC_OBJECT( p_interaction ); } +static void interaction_Destructor( vlc_object_t *p_interaction ) +{ + vlc_thread_join( p_interaction ); +} + +/********************************************************************** + * The following functions are local + **********************************************************************/ + +/* Get the interaction object. Create it if needed */ +static interaction_t * InteractionGet( vlc_object_t *p_this ) +{ + return vlc_object_find( p_this, VLC_OBJECT_INTERACTION, FIND_ANYWHERE ); +} + + /* Look for an interface suitable for interaction */ static void InteractionSearchInterface( interaction_t *p_interaction ) { @@ -550,9 +560,6 @@ static void InteractionLoop( vlc_object_t *p_this ) DialogDestroy( p_dialog ); REMOVE_ELEM( p_interaction->pp_dialogs, p_interaction->i_dialogs, i ); } - - vlc_object_detach( p_this ); - vlc_object_release( p_this ); } /** diff --git a/src/libvlc-common.c b/src/libvlc-common.c index 9e33d92beb..3f7a9d124c 100644 --- a/src/libvlc-common.c +++ b/src/libvlc-common.c @@ -42,6 +42,7 @@ #include "modules/modules.h" #include "config/configuration.h" +#include "interface/interface.h" #include /* ENOMEM */ #include /* sprintf() */ @@ -192,6 +193,7 @@ libvlc_int_t * libvlc_InternalCreate( void ) return NULL; } p_libvlc->p_playlist = NULL; + p_libvlc->p_interaction = NULL; p_libvlc->psz_object_name = "libvlc"; /* Initialize message queue */ @@ -732,6 +734,9 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, /* Do a copy (we don't need to modify the strings) */ memcpy( p_libvlc->p_hotkeys, libvlc_hotkeys, libvlc_hotkeys_size ); + /* Initialize interaction */ + p_libvlc->p_interaction = interaction_Init( p_libvlc ); + /* Initialize playlist and get commandline files */ playlist_ThreadCreate( p_libvlc ); if( !p_libvlc->p_playlist ) @@ -945,6 +950,10 @@ int libvlc_InternalCleanup( libvlc_int_t *p_libvlc ) aout_Delete( p_aout ); } + /* Free interaction */ + msg_Dbg( p_libvlc, "removing interaction" ); + vlc_object_release( p_libvlc->p_interaction ); + stats_TimersDumpAll( p_libvlc ); stats_TimersClean( p_libvlc ); -- 2.39.2