]> git.sesse.net Git - vlc/commitdiff
* New pthread implementation for WinNT/2K/XP. This implementation shouldn't
authorGildas Bazin <gbazin@videolan.org>
Tue, 2 Apr 2002 23:43:57 +0000 (23:43 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 2 Apr 2002 23:43:57 +0000 (23:43 +0000)
  be subject to race conditions as it is using SignalObjectAndWait() from the
  Win32 API.
  As this should be somehow slower than the old method (still used on Win9x),
  you can specify that you want to use the old method with the "fast_pthread"
  config option.

* Added a new p_main_sys global variable. This variable is a pointer to an
  OS specific structure which is defined in *_specific.h. This structure can
  be filled by the already existing System_Init() function and is a nice
  way to avoid too many #ifdefs.

include/beos_specific.h
include/common.h
include/darwin_specific.h
include/os_specific.h [new file with mode: 0644]
include/threads.h
include/videolan/vlc.h
include/win32_specific.h
src/interface/main.c
src/misc/modules_plugin.h
src/misc/win32_specific.c

index 19c9f36da65166eeb076b9a5230b429a6a164ade..faf6351e52bc8b2c227e58842f5772ecc00d9bdf 100644 (file)
@@ -2,7 +2,7 @@
  * beos_specific.h: BeOS specific features 
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: beos_specific.h,v 1.6 2001/05/06 04:32:02 sam Exp $
+ * $Id: beos_specific.h,v 1.7 2002/04/02 23:43:57 gbazin Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *
@@ -29,8 +29,6 @@
 extern "C" {
 #endif
 
-void    system_Init ( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] );
-void    system_End  ( void );
 char  * system_GetProgramPath( void );
 
 #ifdef __cplusplus
index 7eecb0426b8062f74ff5426871f2ded3f9e28b80..e38142f4838dd153d6c822db8dd5ba5aaf55ccfc 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of useful common types and macros definitions
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: common.h,v 1.90 2002/04/01 21:54:26 gbazin Exp $
+ * $Id: common.h,v 1.91 2002/04/02 23:43:57 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -108,6 +108,11 @@ typedef s64 mtime_t;
  * Classes declaration
  *****************************************************************************/
 
+/* System */
+struct main_sys_s;
+
+typedef struct main_sys_s *             p_main_sys_t;
+
 /* Plugins */
 struct plugin_bank_s;
 struct plugin_info_s;
@@ -115,7 +120,7 @@ struct plugin_info_s;
 typedef struct plugin_bank_s *          p_plugin_bank_t;
 typedef struct plugin_info_s *          p_plugin_info_t;
 
-/* Plugins */
+/* Playlist */
 struct playlist_s;
 struct playlist_item_s;
 struct module_s;
@@ -472,6 +477,7 @@ typedef __int64 off_t;
 typedef struct module_symbols_s
 {
     struct main_s* p_main;
+    struct main_sys_s* p_main_sys;
     struct module_bank_s* p_module_bank;
     struct input_bank_s* p_input_bank;
     struct aout_bank_s*  p_aout_bank;
index cab810ec731048c1d60d42baf6af924226b81c14..bc4f9a8b5d56a561b17133a1cc3b4e9354cf78b7 100644 (file)
@@ -2,7 +2,7 @@
  * darwin_specific.h: Darwin specific features 
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: darwin_specific.h,v 1.2 2001/05/06 04:32:02 sam Exp $
+ * $Id: darwin_specific.h,v 1.3 2002/04/02 23:43:57 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -24,7 +24,4 @@
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
-void    system_Init ( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] );
-void    system_End  ( void );
 char  * system_GetProgramPath( void );
-
diff --git a/include/os_specific.h b/include/os_specific.h
new file mode 100644 (file)
index 0000000..80c54b2
--- /dev/null
@@ -0,0 +1,60 @@
+/*****************************************************************************
+ * os_specific.h: OS specific features
+ *****************************************************************************
+ * Copyright (C) 2001 VideoLAN
+ * $Id: os_specific.h,v 1.1 2002/04/02 23:43:57 gbazin Exp $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *          Gildas Bazin <gbazin@netcourrier.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+#ifdef SYS_BEOS
+#   include "beos_specific.h"
+#endif
+#ifdef SYS_DARWIN
+#   include "darwin_specific.h"
+#endif
+#ifdef WIN32
+#   include "win32_specific.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************
+ * main_sys_t: system specific descriptor
+ ****************************************************************************/
+struct main_sys_s;
+
+#ifndef PLUGIN
+extern struct main_sys_s *p_main_sys;
+#else
+#   define p_main_sys (p_symbols->p_main_sys)
+#endif
+
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+void system_Init ( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] );
+void system_Configure  ( void );
+void system_End  ( void );
+
+#ifdef __cplusplus
+}
+#endif
index 59a4684bb39d1aeff8a3491812dd3686e14bae42..4adb89ce6efcae6559c564a65877bb1793f96fb8 100644 (file)
@@ -3,7 +3,7 @@
  * This header provides a portable threads implementation.
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: threads.h,v 1.38 2002/03/28 10:17:06 gbazin Exp $
+ * $Id: threads.h,v 1.39 2002/04/02 23:43:57 gbazin Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@via.ecp.fr>
@@ -53,8 +53,6 @@ int pthread_mutexattr_setkind_np( pthread_mutexattr_t *attr, int kind );
 #   include <byteorder.h>
 
 #elif defined( WIN32 )
-#define WIN32_LEAN_AND_MEAN
-#   include <windows.h>
 #   include <process.h>
 
 #else
@@ -147,8 +145,13 @@ typedef struct
 } vlc_cond_t;
 
 #elif defined( WIN32 )
-typedef HANDLE           vlc_thread_t;
-typedef CRITICAL_SECTION vlc_mutex_t;
+typedef HANDLE vlc_thread_t;
+
+typedef struct
+{
+    CRITICAL_SECTION csection;
+    HANDLE           mutex;
+} vlc_mutex_t;
 
 typedef struct
 {
@@ -308,8 +311,22 @@ static __inline__ int vlc_mutex_init( vlc_mutex_t *p_mutex )
     return B_OK;
 
 #elif defined( WIN32 )
-    InitializeCriticalSection( p_mutex );
-    return 0;
+    /* We use mutexes on WinNT/2K/XP because we can use the SignalObjectAndWait
+     * function and have a 100% correct vlc_cond_wait() implementation.
+     * As this function is not available on Win9x, we can use the faster
+     * CriticalSections */
+    if( (GetVersion() < 0x80000000) && !p_main_sys->b_fast_pthread )
+    {
+        /* We are running on NT/2K/XP, we can use SignalObjectAndWait */
+        p_mutex->mutex = CreateMutex( 0, FALSE, 0 );
+        return ( p_mutex->mutex ? 0 : 1 );
+    }
+    else
+    {
+        InitializeCriticalSection( &p_mutex->csection );
+        p_mutex->mutex = NULL;
+        return 0;
+    }
 
 #endif
 }
@@ -364,7 +381,14 @@ static __inline__ int _vlc_mutex_lock( char * psz_file, int i_line,
     return err;
 
 #elif defined( WIN32 )
-    EnterCriticalSection( p_mutex );
+    if( p_mutex->mutex )
+    {
+        WaitForSingleObject( p_mutex->mutex, INFINITE );
+    }
+    else
+    {
+        EnterCriticalSection( &p_mutex->csection );
+    }
     return 0;
 
 #endif
@@ -418,7 +442,14 @@ static __inline__ int _vlc_mutex_unlock( char * psz_file, int i_line,
     return B_OK;
 
 #elif defined( WIN32 )
-    LeaveCriticalSection( p_mutex );
+    if( p_mutex->mutex )
+    {
+        ReleaseMutex( p_mutex->mutex );
+    }
+    else
+    {
+        LeaveCriticalSection( &p_mutex->csection );
+    }
     return 0;
 
 #endif
@@ -466,7 +497,14 @@ static __inline__ int _vlc_mutex_destroy( char * psz_file, int i_line,
     return B_OK;
 
 #elif defined( WIN32 )
-    DeleteCriticalSection( p_mutex );
+    if( p_mutex->mutex )
+    {
+        CloseHandle( p_mutex->mutex );
+    }
+    else
+    {
+        DeleteCriticalSection( &p_mutex->csection );
+    }
     return 0;
 
 #endif    
@@ -664,7 +702,7 @@ static __inline__ int vlc_cond_broadcast( vlc_cond_t *p_condvar )
     while( p_condvar->i_waiting_threads )
     {
         PulseEvent( p_condvar->signal );
-        Sleep( 0 ); /* deschedule the current thread */
+        Sleep( 1 ); /* deschedule the current thread */
     }
     return 0;
 
@@ -777,13 +815,18 @@ static __inline__ int _vlc_cond_wait( char * psz_file, int i_line,
 
     p_condvar->i_waiting_threads ++;
 
-    /* Release the mutex */
-    vlc_mutex_unlock( p_mutex );
-
-    i_result = WaitForSingleObject( p_condvar->signal, INFINITE); 
-
-    /* maybe we should protect this with a mutex ? */
-    p_condvar->i_waiting_threads --;
+    if( p_mutex->mutex )
+    {
+        p_main_sys->SignalObjectAndWait( p_mutex->mutex, p_condvar->signal,
+                                        INFINITE, FALSE );
+    }
+    else
+    {
+        /* Release the mutex */
+        vlc_mutex_unlock( p_mutex );
+        i_result = WaitForSingleObject( p_condvar->signal, INFINITE); 
+        p_condvar->i_waiting_threads --;
+    }
 
     /* Reacquire the mutex before returning. */
     vlc_mutex_lock( p_mutex );
@@ -892,19 +935,12 @@ static __inline__ int _vlc_thread_create( char * psz_file, int i_line,
     i_ret = resume_thread( *p_thread );
 
 #elif defined( WIN32 )
-#if 0
-    DWORD threadID;
-    /* This method is not recommended when using the MSVCRT C library,
-     * so we'll have to use _beginthreadex instead */
-    *p_thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) func, 
-                             p_data, 0, &threadID);
-#endif
     unsigned threadID;
     /* When using the MSVCRT C library you have to use the _beginthreadex
      * function instead of CreateThread, otherwise you'll end up with memory
-     * leaks and the signal function not working */
-    *p_thread = (HANDLE)_beginthreadex(NULL, 0, (PTHREAD_START) func, 
-                             p_data, 0, &threadID);
+     * leaks and the signal functions not working */
+    *p_thread = (HANDLE)_beginthreadex( NULL, 0, (PTHREAD_START) func, 
+                                        p_data, 0, &threadID );
     
     i_ret = ( *p_thread ? 0 : 1 );
 
@@ -958,9 +994,6 @@ static __inline__ void vlc_thread_exit( void )
     exit_thread( 0 );
 
 #elif defined( WIN32 )
-#if 0
-    ExitThread( 0 );
-#endif
     /* For now we don't close the thread handles (because of race conditions).
      * Need to be looked at. */
     _endthreadex(0);
@@ -1037,4 +1070,3 @@ static void *vlc_thread_wrapper( void *p_wrapper )
     return func( p_data );
 }
 #endif
-
index ed99f9f01bcd2a92f5c72bd932cf3c9a51f6a42e..41e1e153ad7994f33d8fce07cf7bde73af8c0d41 100644 (file)
@@ -2,7 +2,7 @@
  * vlc.h: global header for vlc
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc.h,v 1.5 2002/03/03 04:37:29 sam Exp $
+ * $Id: vlc.h,v 1.6 2002/04/02 23:43:57 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
 
 #include "common.h"
 
-#ifdef SYS_BEOS
-#   include "beos_specific.h"
-#endif
-#ifdef SYS_DARWIN
-#   include "darwin_specific.h"
-#endif
-#ifdef WIN32
-#   include "win32_specific.h"
-#endif
+#include "os_specific.h"
 
 #include "intf_msg.h"
 #include "threads.h"
index c6ccb6a64f9a750743fcd33d04f39bae1556b5b9..18a2c210335cc884a2bfb68003d14be90f99f8b7 100644 (file)
@@ -2,9 +2,10 @@
  * win32_specific.h: Win32 specific features 
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: win32_specific.h,v 1.1 2001/11/12 22:42:56 sam Exp $
+ * $Id: win32_specific.h,v 1.2 2002/04/02 23:43:57 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
+ *          Gildas Bazin <gbazin@netcourrier.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+typedef BOOL (WINAPI *SIGNALOBJECTANDWAIT)( HANDLE, HANDLE, DWORD, BOOL );
+
 /*****************************************************************************
- * Prototypes
+ * main_sys_t: system specific descriptor
+ *****************************************************************************
+ * This structure is a system specific descriptor. It describes the Win32
+ * properties of the program.
  *****************************************************************************/
-void    system_Init ( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] );
-void    system_End  ( void );
+typedef struct main_sys_s
+{
+    SIGNALOBJECTANDWAIT SignalObjectAndWait;
+    boolean_t b_fast_pthread;
 
+} main_sys_t;
index 2c2253afd01c0d8fc66909f34fc15a168a5492cc..9bcafe5113f62497779002e68e05120f0d820633 100644 (file)
@@ -4,7 +4,7 @@
  * and spawn threads.
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: main.c,v 1.174 2002/04/02 21:56:19 ipkiss Exp $
+ * $Id: main.c,v 1.175 2002/04/02 23:43:57 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
 #define MEMCPY_TEXT "memory copy method"
 #define MEMCPY_LONGTEXT NULL
 
+#define FAST_PTHREAD_TEXT "fast pthread on NT/2K/XP (developpers only)"
+#define FAST_PTHREAD_LONGTEXT "On Windows NT/2K/XP we use a slow but correct "\
+                              "pthread implementation, you can also use this "\
+                              "faster implementation but you might "\
+                              "experience problems with it"
+
 /* Quick usage guide
 MODULE_CONFIG_START
 MODULE_CONFIG_STOP
@@ -376,6 +382,10 @@ ADD_BOOL    ( "playlist_loop", NULL, PLAYLIST_LOOP_TEXT, PLAYLIST_LOOP_LONGTEXT
 ADD_CATEGORY_HINT( "Miscellaneous", NULL )
 ADD_PLUGIN  ( "memcpy", MODULE_CAPABILITY_MEMCPY, NULL, NULL, MEMCPY_TEXT, MEMCPY_LONGTEXT )
 
+#if defined(WIN32)
+ADD_BOOL    ( "fast_pthread", NULL, FAST_PTHREAD_TEXT, FAST_PTHREAD_LONGTEXT )
+#endif
+
 MODULE_CONFIG_STOP
 
 MODULE_INIT_START
@@ -413,6 +423,7 @@ static module_config_t p_help_config[] = {
  * Global variables - these are the only ones, see main.h and modules.h
  *****************************************************************************/
 main_t        *p_main;
+p_main_sys_t  p_main_sys;
 module_bank_t *p_module_bank;
 input_bank_t  *p_input_bank;
 aout_bank_t   *p_aout_bank;
@@ -642,6 +653,13 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
     }
 
 
+    /*
+     * System specific configuration
+     */
+#if defined( WIN32 )
+    system_Configure();
+#endif
+
     /* p_main inititalization. FIXME ? */
     p_main->i_desync = (mtime_t)config_GetIntVariable( "desync" )
       * (mtime_t)1000;
index c2633fad04184b44ff81275703691ae2dcf5745f..0ec0e9fbac005542aae77571542d36e7149f2fcc 100644 (file)
@@ -2,7 +2,7 @@
  * modules_plugin.h : Plugin management functions used by the core application.
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: modules_plugin.h,v 1.17 2002/03/20 03:43:51 sam Exp $
+ * $Id: modules_plugin.h,v 1.18 2002/04/02 23:43:57 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -162,6 +162,7 @@ module_error( void )
  *****************************************************************************/
 #define STORE_SYMBOLS( p_symbols ) \
     (p_symbols)->p_main = p_main; \
+    (p_symbols)->p_main_sys = p_main_sys; \
     (p_symbols)->p_module_bank = p_module_bank; \
     (p_symbols)->p_input_bank = p_input_bank; \
     (p_symbols)->p_aout_bank = p_aout_bank; \
index 9c4396e6289b6792a7c2bc203ce3e7169603ee42..b5344340c3ed39a12d9b1a14aafb1446a230b5d7 100644 (file)
@@ -2,9 +2,10 @@
  * win32_specific.c: Win32 specific features 
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: win32_specific.c,v 1.5 2001/12/30 07:09:56 sam Exp $
+ * $Id: win32_specific.c,v 1.6 2002/04/02 23:43:57 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
+ *          Gildas Bazin <gbazin@netcourrier.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
+#include <errno.h>                                                 /* ENOMEM */
 #include <string.h>                                              /* strdup() */
 #include <stdlib.h>                                                /* free() */
 #include <fcntl.h>
 #include <videolan/vlc.h>
 
 /*****************************************************************************
- * system_Init: initialize winsock.
+ * system_Init: initialize winsock and misc other things.
  *****************************************************************************/
 void system_Init( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] )
 {
     WSADATA Data;
     int i_err;
+    HINSTANCE hInstLib;
+
+    /* Allocate structure */
+    p_main_sys = malloc( sizeof( main_sys_t ) );
+    if( p_main_sys == NULL )
+    {
+        intf_ErrMsg( "init error: can't create p_main_sys (%s)",
+                    strerror(ENOMEM) );
+        exit(-1);
+    }
+
+    /* dynamically get the address of SignalObjectAndWait */
+    hInstLib = LoadLibrary( "kernel32" );
+    p_main_sys->SignalObjectAndWait =
+        (SIGNALOBJECTANDWAIT)GetProcAddress( hInstLib, "SignalObjectAndWait" );
 
     /* WinSock Library Init. */
     i_err = WSAStartup( MAKEWORD( 1, 1 ), &Data );
@@ -47,6 +64,14 @@ void system_Init( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] )
     _fmode = _O_BINARY;  /* sets the default file-translation mode */
 }
 
+/*****************************************************************************
+ * system_Configure: check for system specific configuration options.
+ *****************************************************************************/
+void system_Configure( void )
+{
+    p_main_sys->b_fast_pthread = config_GetIntVariable( "fast_pthread" );
+}
+
 /*****************************************************************************
  * system_End: terminate winsock.
  *****************************************************************************/
@@ -54,4 +79,3 @@ void system_End( void )
 {
     WSACleanup();
 }
-