]> git.sesse.net Git - vlc/blobdiff - src/libvlc.c
Correctly handle multiple clients in httpd
[vlc] / src / libvlc.c
index 75d4cfbfa3703b518708e0fd5ac475da60e38789..f085509183143e89062601670ec92be13863aa2d 100644 (file)
 #   include <hal/libhal.h>
 #endif
 
-#if defined(__GNUC__)
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
-#define USE_SYNC
-#endif
-#endif
-
 #include <vlc_playlist.h>
 #include <vlc_interface.h>
 
@@ -126,13 +120,14 @@ static bool b_daemon = false;
  */
 void *vlc_gc_init (gc_object_t *p_gc, void (*pf_destruct) (gc_object_t *))
 {
-    /* There is no point in using the GC if there is destructor... */
+    /* There is no point in using the GC if there is no destructor... */
     assert (pf_destruct);
     p_gc->pf_destructor = pf_destruct;
 
     p_gc->refs = 1;
-#ifdef USE_SYNC
+#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
     __sync_synchronize ();
+#elif defined (WIN32) && defined (__GNUC__)
 #elif defined(__APPLE__)
     OSMemoryBarrier ();
 #else
@@ -154,21 +149,20 @@ void *vlc_hold (gc_object_t * p_gc)
     uintptr_t refs;
     assert( p_gc );
 
-#if defined (WIN32)
-    refs = -1 +
-        __builtin_choose_expr (sizeof (uintptr_t) == 4,
-            InterlockedIncrement (&p_gc->refs),
-            InterlockedIncrement64 (&p_gc->refs));
-#elif defined (USE_SYNC)
-    refs = __sync_fetch_and_add (&p_gc->refs, 1);
+#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+    refs = __sync_add_and_fetch (&p_gc->refs, 1);
+#elif defined (WIN64)
+    refs = InterlockedIncrement64 (&p_gc->refs);
+#elif defined (WIN32)
+    refs = InterlockedIncrement (&p_gc->refs);
 #elif defined(__APPLE__)
-    refs = OSAtomicIncrement32Barrier((int*)&p_gc->refs) - 1;
+    refs = OSAtomicIncrement32Barrier((int*)&p_gc->refs);
 #else
     vlc_spin_lock (&p_gc->spin);
-    refs = p_gc->refs++;
+    refs = ++p_gc->refs;
     vlc_spin_unlock (&p_gc->spin);
 #endif
-    assert (refs > 0);
+    assert (refs != 1); /* there had to be a reference already */
     return p_gc;
 }
 
@@ -182,25 +176,25 @@ void vlc_release (gc_object_t *p_gc)
 
     assert( p_gc );
 
-#if defined (WIN32)
-    refs = 1 +
-        __builtin_choose_expr (sizeof (uintptr_t) == 4,
-            InterlockedDecrement (&p_gc->refs),
-            InterlockedDecrement64 (&p_gc->refs));
-#elif defined (USE_SYNC)
-    refs = __sync_fetch_and_sub (&p_gc->refs, 1);
+#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+    refs = __sync_sub_and_fetch (&p_gc->refs, 1);
+#elif defined (WIN64)
+    refs = InterlockedDecrement64 (&p_gc->refs);
+#elif defined (WIN32)
+    refs = InterlockedDecrement (&p_gc->refs);
 #elif defined(__APPLE__)
-    refs = OSAtomicDecrement32Barrier((int*)&p_gc->refs) + 1;
+    refs = OSAtomicDecrement32Barrier((int*)&p_gc->refs);
 #else
     vlc_spin_lock (&p_gc->spin);
-    refs = p_gc->refs--;
+    refs = --p_gc->refs;
     vlc_spin_unlock (&p_gc->spin);
 #endif
 
-    assert (refs > 0);
-    if (refs == 1)
+    assert (refs != (uintptr_t)(-1)); /* reference underflow?! */
+    if (refs == 0)
     {
 #ifdef USE_SYNC
+#elif defined (WIN32) && defined (__GNUC__)
 #elif defined(__APPLE__)
 #else
         vlc_spin_destroy (&p_gc->spin);
@@ -234,6 +228,8 @@ static int  VerboseCallback( vlc_object_t *, char const *,
 
 static void InitDeviceValues( libvlc_int_t * );
 
+static vlc_mutex_t global_lock = VLC_STATIC_MUTEX;
+
 /**
  * Allocate a libvlc instance, initialize global data if needed
  * It also initializes the threading system
@@ -244,28 +240,22 @@ libvlc_int_t * libvlc_InternalCreate( void )
     libvlc_priv_t *priv;
     char *psz_env = NULL;
 
-    /* vlc_threads_init *must* be the first internal call! No other call is
-     * allowed before the thread system has been initialized. */
-    if (vlc_threads_init ())
-        return NULL;
-
     /* Now that the thread system is initialized, we don't have much, but
      * at least we have variables */
-    vlc_mutex_t *lock = var_AcquireMutex( "libvlc" );
+    vlc_mutex_lock( &global_lock );
     if( i_instances == 0 )
     {
         /* Guess what CPU we have */
         cpu_flags = CPUCapabilities();
         /* The module bank will be initialized later */
-        p_module_bank = NULL;
     }
 
     /* Allocate a libvlc instance object */
     p_libvlc = __vlc_custom_create( NULL, sizeof (*priv),
-                                  VLC_OBJECT_LIBVLC, "libvlc" );
+                                  VLC_OBJECT_GENERIC, "libvlc" );
     if( p_libvlc != NULL )
         i_instances++;
-    vlc_mutex_unlock( lock );
+    vlc_mutex_unlock( &global_lock );
 
     if( p_libvlc == NULL )
         return NULL;
@@ -375,10 +365,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
     priv->psz_configfile = config_GetCustomConfigFile( p_libvlc );
 
     /* Check for plugins cache options */
-    if( config_GetInt( p_libvlc, "reset-plugins-cache" ) > 0 )
-    {
-        p_module_bank->b_cache_delete = true;
-    }
+    bool b_cache_delete = config_GetInt( p_libvlc, "reset-plugins-cache" ) > 0;
 
     /* Will be re-done properly later on */
     priv->i_verbose = config_GetInt( p_libvlc, "verbose" );
@@ -469,8 +456,6 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
     psz_language = config_GetPsz( p_libvlc, "language" );
     if( psz_language && *psz_language && strcmp( psz_language, "auto" ) )
     {
-        bool b_cache_delete = p_module_bank->b_cache_delete;
-
         /* Reset the default domain */
         SetLanguage( psz_language );
 
@@ -482,7 +467,6 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
         if( !config_GetInt( p_libvlc, "ignore-config" ) )
             config_LoadConfigFile( p_libvlc, "main" );
         config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
-        p_module_bank->b_cache_delete = b_cache_delete;
     }
     free( psz_language );
 # endif
@@ -495,7 +479,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
      * default values.
      */
     module_LoadBuiltins( p_libvlc );
-    module_LoadPlugins( p_libvlc );
+    module_LoadPlugins( p_libvlc, b_cache_delete );
     if( p_libvlc->b_die )
     {
         b_exit = true;
@@ -504,7 +488,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
     size_t module_count;
     module_t **list = module_list_get( &module_count );
     module_list_free( list );
-    msg_Dbg( p_libvlc, "module bank initialized (%u modules)", module_count );
+    msg_Dbg( p_libvlc, "module bank initialized (%zu modules)", module_count );
 
     /* Check for help on modules */
     if( (p_tmp = config_GetPsz( p_libvlc, "module" )) )
@@ -760,11 +744,6 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
     if( priv->b_color )
         priv->b_color = config_GetInt( p_libvlc, "color" ) > 0;
 
-    /*
-     * Output messages that may still be in the queue
-     */
-    msg_Flush( p_libvlc );
-
     if( !config_GetInt( p_libvlc, "fpu" ) )
         cpu_flags &= ~CPU_CAPABILITY_FPU;
 
@@ -825,6 +804,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
     vlc_mutex_init( &p_libvlc->p_stats->lock );
     priv->p_stats_computer = NULL;
 
+    priv->i_last_input_id = 0; /* Not very safe, should be removed */
+
     /*
      * Initialize hotkey handling
      */
@@ -902,10 +883,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
             *psz_parser = '\0';
             psz_parser++;
         }
-        psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
-        if( psz_temp )
+        if( asprintf( &psz_temp, "%s,none", psz_module ) != -1)
         {
-            sprintf( psz_temp, "%s,none", psz_module );
             libvlc_InternalAddIntf( p_libvlc, psz_temp );
             free( psz_temp );
         }
@@ -943,7 +922,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
     }
 #endif
 
-    if( config_GetInt( p_libvlc, "file-logging" ) > 0 )
+    if( (config_GetInt( p_libvlc, "file-logging" ) > 0) &&
+        !config_GetInt( p_libvlc, "syslog" ) )
     {
         libvlc_InternalAddIntf( p_libvlc, "logger,none" );
     }
@@ -1145,7 +1125,7 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
                      p_libvlc->p_hotkeys );
     FREENULL( p_libvlc->p_hotkeys );
 
-    vlc_mutex_t *lock = var_AcquireMutex( "libvlc" );
+    vlc_mutex_lock( &global_lock );
     i_instances--;
 
     if( i_instances == 0 )
@@ -1153,9 +1133,8 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
         /* System specific cleaning code */
         system_End( p_libvlc );
     }
-    vlc_mutex_unlock( lock );
+    vlc_mutex_unlock( &global_lock );
 
-    msg_Flush( p_libvlc );
     msg_Destroy( p_libvlc );
 
     /* Destroy mutexes */
@@ -1165,11 +1144,6 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
     vlc_object_release( p_libvlc );
     p_libvlc = NULL;
 
-    /* Stop thread system: last one out please shut the door!
-     * The number of initializations of the thread system is counted, we
-     * can call this each time */
-    vlc_threads_end ();
-
     return VLC_SUCCESS;
 }
 
@@ -2064,7 +2038,7 @@ static int ConsoleWidth( void )
             i_width = 80;
         pclose( file );
     }
-#else
+#elif !defined (UNDER_CE)
     CONSOLE_SCREEN_BUFFER_INFO buf;
 
     if (GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &buf))