interaction: Keep a libvlc's global interaction object reference around, and properly...
authorPierre d'Herbemont <pdherbemont@videolan.org>
Sat, 22 Mar 2008 23:55:15 +0000 (00:55 +0100)
committerPierre d'Herbemont <pdherbemont@videolan.org>
Sat, 22 Mar 2008 23:55:15 +0000 (00:55 +0100)
include/main.h
src/interface/interaction.c
src/libvlc-common.c

index 7527d9e..596de28 100644 (file)
@@ -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
index 7763186..fab49f7 100644 (file)
 #include <vlc/vlc.h>
 
 #include <vlc_interface.h>
+#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 );
 }
 
 /**
index 9e33d92..3f7a9d1 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "modules/modules.h"
 #include "config/configuration.h"
+#include "interface/interface.h"
 
 #include <errno.h>                                                 /* ENOMEM */
 #include <stdio.h>                                              /* 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 );