]> git.sesse.net Git - vlc/blobdiff - src/libvlc.c
Vout: Small rewording
[vlc] / src / libvlc.c
index d6afbc061d1ca93a25525d96774da81253c9b171..f2974204dd1a2a34beccb179f788d4791c17ff61 100644 (file)
@@ -99,7 +99,6 @@
 /*****************************************************************************
  * The evil global variables. We handle them with care, don't worry.
  *****************************************************************************/
-static libvlc_int_t *    p_static_vlc = NULL;
 static unsigned          i_instances = 0;
 
 #ifndef WIN32
@@ -146,6 +145,7 @@ void *vlc_hold (gc_object_t * p_gc)
 {
     uintptr_t refs;
     assert( p_gc );
+    assert ((((uintptr_t)&p_gc->refs) & (sizeof (void *) - 1)) == 0); /* alignment */
 
 #if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
     refs = __sync_add_and_fetch (&p_gc->refs, 1);
@@ -173,6 +173,7 @@ void vlc_release (gc_object_t *p_gc)
     unsigned refs;
 
     assert( p_gc );
+    assert ((((uintptr_t)&p_gc->refs) & (sizeof (void *) - 1)) == 0); /* alignment */
 
 #if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
     refs = __sync_sub_and_fetch (&p_gc->refs, 1);
@@ -282,9 +283,7 @@ libvlc_int_t * libvlc_InternalCreate( void )
     /* Initialize mutexes */
     vlc_mutex_init( &priv->timer_lock );
     vlc_mutex_init( &priv->config_lock );
-
-    /* Store data for the non-reentrant API */
-    p_static_vlc = p_libvlc;
+    vlc_cond_init( &priv->exiting );
 
     return p_libvlc;
 }
@@ -432,6 +431,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
 
     if( b_exit )
     {
+        free( priv->psz_configfile );
         module_EndBank( p_libvlc );
         return i_ret;
     }
@@ -542,6 +542,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
 
     if( b_exit )
     {
+        free( priv->psz_configfile );
         module_EndBank( p_libvlc );
         return i_ret;
     }
@@ -569,6 +570,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
                  "that they are valid.\n" );
         PauseConsole();
 #endif
+        free( priv->psz_configfile );
         module_EndBank( p_libvlc );
         return VLC_EGENERIC;
     }
@@ -721,6 +723,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
                             "-dontprintthatone\n"
                             "(keyword 'all' to applies to all objects)\n");
                     free( psz_verbose_objects );
+                    /* FIXME: leaks!!!! */
                     return VLC_EGENERIC;
             }
         }
@@ -794,7 +797,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
     if( !p_libvlc->p_stats )
     {
         vlc_object_release( p_libvlc );
-        return VLC_ENOMEM;
+        return VLC_ENOMEM; /* FIXME: leaks */
     }
     vlc_mutex_init( &p_libvlc->p_stats->lock );
     priv->p_stats_computer = NULL;
@@ -825,16 +828,19 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
             module_unneed( p_libvlc, priv->p_memcpy_module );
         }
         module_EndBank( p_libvlc );
+        free( priv->psz_configfile );
         return VLC_EGENERIC;
     }
     playlist_Activate( p_playlist );
     vlc_object_attach( p_playlist, p_libvlc );
 
+    /* Add service discovery modules */
     psz_modules = config_GetPsz( p_playlist, "services-discovery" );
     if( psz_modules && *psz_modules )
     {
-        /* Add service discovery modules */
-        playlist_ServicesDiscoveryAdd( p_playlist, psz_modules );
+        char *p = psz_modules, *m;
+        while( ( m = strsep( &p, " :," ) ) != NULL )
+            playlist_ServicesDiscoveryAdd( p_playlist, m );
     }
     free( psz_modules );
 
@@ -858,9 +864,12 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
 
     if( psz_modules && *psz_modules && psz_control && *psz_control )
     {
-        psz_modules = (char *)realloc( psz_modules, strlen( psz_modules ) +
-                                                    strlen( psz_control ) + 1 );
-        sprintf( psz_modules, "%s:%s", psz_modules, psz_control );
+        char* psz_tmp;
+        if( asprintf( &psz_tmp, "%s:%s", psz_modules, psz_control ) != -1 )
+        {
+            free( psz_modules );
+            psz_modules = psz_tmp;
+        }
     }
     else if( psz_control && *psz_control )
     {
@@ -892,6 +901,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
      * Always load the hotkeys interface if it exists
      */
     libvlc_InternalAddIntf( p_libvlc, "hotkeys,none" );
+    if( module_exists( "globalhotkeys" ) )
+        libvlc_InternalAddIntf( p_libvlc, "globalhotkeys,none" );
 
 #ifdef HAVE_DBUS
     /* loads dbus control interface if in one-instance mode
@@ -1005,7 +1016,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
     {
         playlist_t *p_playlist = pl_Hold( p_libvlc );
         playlist_AddExt( p_playlist, val.psz_string, NULL, PLAYLIST_INSERT, 0,
-                         -1, NULL, 0, true, pl_Unlocked );
+                         -1, 0, NULL, 0, true, pl_Unlocked );
         pl_Release( p_libvlc );
     }
     free( val.psz_string );
@@ -1017,7 +1028,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
  * Cleanup a libvlc instance. The instance is not completely deallocated
  * \param p_libvlc the instance to clean
  */
-int libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
+void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
 {
     libvlc_priv_t *priv = libvlc_priv (p_libvlc);
     playlist_t    *p_playlist = priv->p_playlist;
@@ -1069,23 +1080,6 @@ int libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
     vlc_mutex_destroy( &p_libvlc->p_stats->lock );
     FREENULL( p_libvlc->p_stats );
 
-    return VLC_SUCCESS;
-}
-
-/**
- * Destroy everything.
- * This function requests the running threads to finish, waits for their
- * termination, and destroys their structure.
- * It stops the thread systems: no instance can run after this has run
- * \param p_libvlc the instance to destroy
- */
-int libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
-{
-    if( !p_libvlc )
-        return VLC_EGENERIC;
-
-    libvlc_priv_t *priv = libvlc_priv( p_libvlc );
-
 #ifndef WIN32
     char* psz_pidfile = NULL;
 
@@ -1118,6 +1112,18 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
     var_DelCallback( p_libvlc, "key-pressed", vlc_key_to_action,
                      p_libvlc->p_hotkeys );
     FREENULL( p_libvlc->p_hotkeys );
+}
+
+/**
+ * Destroy everything.
+ * This function requests the running threads to finish, waits for their
+ * termination, and destroys their structure.
+ * It stops the thread systems: no instance can run after this has run
+ * \param p_libvlc the instance to destroy
+ */
+void libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
+{
+    libvlc_priv_t *priv = libvlc_priv( p_libvlc );
 
     vlc_mutex_lock( &global_lock );
     i_instances--;
@@ -1132,13 +1138,11 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
     msg_Destroy( p_libvlc );
 
     /* Destroy mutexes */
+    vlc_cond_destroy( &priv->exiting );
     vlc_mutex_destroy( &priv->config_lock );
     vlc_mutex_destroy( &priv->timer_lock );
 
     vlc_object_release( p_libvlc );
-    p_libvlc = NULL;
-
-    return VLC_SUCCESS;
 }
 
 /**
@@ -1190,6 +1194,33 @@ int libvlc_InternalAddIntf( libvlc_int_t *p_libvlc, char const *psz_module )
     return VLC_SUCCESS;
 };
 
+/**
+ * Waits until the LibVLC instance gets an exit signal. Normally, this happens
+ * when the user "exits" an interface plugin.
+ */
+void libvlc_InternalWait( libvlc_int_t *p_libvlc )
+{
+    libvlc_priv_t *priv = libvlc_priv( p_libvlc );
+    vlc_object_internals_t *internals = vlc_internals( p_libvlc );
+
+    vlc_object_lock( p_libvlc );
+    while( vlc_object_alive( p_libvlc ) )
+        vlc_cond_wait( &priv->exiting, &internals->lock );
+    vlc_object_unlock( p_libvlc );
+}
+
+/**
+ * Posts an exit signal to LibVLC instance. This will normally initiate the
+ * cleanup and destroy process. It should only be called on behalf of the user.
+ */
+void libvlc_Quit( libvlc_int_t *p_libvlc )
+{
+    libvlc_priv_t *priv = libvlc_priv( p_libvlc );
+
+    vlc_object_kill( p_libvlc );
+    vlc_cond_signal( &priv->exiting ); /* OK, kill took care of the lock */
+}
+
 #if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
     ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
 /*****************************************************************************
@@ -1293,8 +1324,9 @@ static int GetFilenames( libvlc_int_t *p_vlc, int i_argc, const char *ppsz_argv[
 
         playlist_t *p_playlist = pl_Hold( p_vlc );
         playlist_AddExt( p_playlist, ppsz_argv[i_opt], NULL, PLAYLIST_INSERT,
-                         0, -1, ( i_options ? &ppsz_argv[i_opt + 1] : NULL ),
-                         i_options, true, pl_Unlocked );
+                         0, -1,
+                         i_options, ( i_options ? &ppsz_argv[i_opt + 1] : NULL ), VLC_INPUT_OPTION_TRUSTED,
+                         true, pl_Unlocked );
         pl_Release( p_vlc );
     }