From: Gildas Bazin Date: Tue, 2 Apr 2002 23:43:57 +0000 (+0000) Subject: * New pthread implementation for WinNT/2K/XP. This implementation shouldn't X-Git-Tag: 0.3.0~24 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=4f08a70d2125a8ebcf05b82b73fcdb3a1d56cae3;p=vlc * New pthread implementation for WinNT/2K/XP. This implementation shouldn't 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. --- diff --git a/include/beos_specific.h b/include/beos_specific.h index 19c9f36da6..faf6351e52 100644 --- a/include/beos_specific.h +++ b/include/beos_specific.h @@ -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 * @@ -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 diff --git a/include/common.h b/include/common.h index 7eecb0426b..e38142f483 100644 --- a/include/common.h +++ b/include/common.h @@ -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 * Vincent Seguin @@ -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; diff --git a/include/darwin_specific.h b/include/darwin_specific.h index cab810ec73..bc4f9a8b5d 100644 --- a/include/darwin_specific.h +++ b/include/darwin_specific.h @@ -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 * @@ -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 index 0000000000..80c54b2a64 --- /dev/null +++ b/include/os_specific.h @@ -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 + * Gildas Bazin + * + * 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 diff --git a/include/threads.h b/include/threads.h index 59a4684bb3..4adb89ce6e 100644 --- a/include/threads.h +++ b/include/threads.h @@ -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 * Samuel Hocevar @@ -53,8 +53,6 @@ int pthread_mutexattr_setkind_np( pthread_mutexattr_t *attr, int kind ); # include #elif defined( WIN32 ) -#define WIN32_LEAN_AND_MEAN -# include # include #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 - diff --git a/include/videolan/vlc.h b/include/videolan/vlc.h index ed99f9f01b..41e1e153ad 100644 --- a/include/videolan/vlc.h +++ b/include/videolan/vlc.h @@ -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 * Vincent Seguin @@ -35,15 +35,7 @@ #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" diff --git a/include/win32_specific.h b/include/win32_specific.h index c6ccb6a64f..18a2c21033 100644 --- a/include/win32_specific.h +++ b/include/win32_specific.h @@ -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 + * Gildas Bazin * * 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 @@ -21,9 +22,20 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ +#define WIN32_LEAN_AND_MEAN +#include + +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; diff --git a/src/interface/main.c b/src/interface/main.c index 2c2253afd0..9bcafe5113 100644 --- a/src/interface/main.c +++ b/src/interface/main.c @@ -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 * Samuel Hocevar @@ -282,6 +282,12 @@ #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; diff --git a/src/misc/modules_plugin.h b/src/misc/modules_plugin.h index c2633fad04..0ec0e9fbac 100644 --- a/src/misc/modules_plugin.h +++ b/src/misc/modules_plugin.h @@ -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 * @@ -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; \ diff --git a/src/misc/win32_specific.c b/src/misc/win32_specific.c index 9c4396e628..b5344340c3 100644 --- a/src/misc/win32_specific.c +++ b/src/misc/win32_specific.c @@ -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 + * Gildas Bazin * * 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 /* ENOMEM */ #include /* strdup() */ #include /* free() */ #include @@ -29,12 +31,27 @@ #include /***************************************************************************** - * 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(); } -