From: Anton Mitrofanov Date: Fri, 22 Sep 2017 14:05:06 +0000 (+0300) Subject: Fix thread safety of x264_threading_init() and use of X264_PTHREAD_MUTEX_INITIALIZER... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fefc3fa1fa98a7bac4eaf3c8e6e1c52b7e427ddd;p=libx264 Fix thread safety of x264_threading_init() and use of X264_PTHREAD_MUTEX_INITIALIZER with win32thread --- diff --git a/common/osdep.c b/common/osdep.c index a8cf1d7c..deb546ea 100644 --- a/common/osdep.c +++ b/common/osdep.c @@ -72,11 +72,8 @@ static void threading_destroy( void ) #endif } -int x264_threading_init( void ) +static int threading_init( void ) { - /* if already init, then do nothing */ - if( InterlockedCompareExchange( &threading_is_init, 1, 0 ) ) - return 0; #if PTW32_STATIC_LIB /* if static pthread-win32 is already initialized, then do nothing */ if( ptw32_processInitialized ) @@ -89,7 +86,24 @@ int x264_threading_init( void ) #endif /* register cleanup to run at process termination */ atexit( threading_destroy ); + return 0; +} +int x264_threading_init( void ) +{ + LONG state; + while( (state = InterlockedCompareExchange( &threading_is_init, -1, 0 )) != 0 ) + { + /* if already init, then do nothing */ + if( state > 0 ) + return 0; + } + if( threading_init() < 0 ) + { + InterlockedExchange( &threading_is_init, 0 ); + return -1; + } + InterlockedExchange( &threading_is_init, 1 ); return 0; } #endif diff --git a/common/threadpool.c b/common/threadpool.c index 61d75ce0..f707cfdd 100644 --- a/common/threadpool.c +++ b/common/threadpool.c @@ -78,6 +78,9 @@ int x264_threadpool_init( x264_threadpool_t **p_pool, int threads, if( threads <= 0 ) return -1; + if( x264_threading_init() < 0 ) + return -1; + x264_threadpool_t *pool; CHECKED_MALLOCZERO( pool, sizeof(x264_threadpool_t) ); *p_pool = pool; diff --git a/common/win32thread.c b/common/win32thread.c index d12f16e7..3b71078a 100644 --- a/common/win32thread.c +++ b/common/win32thread.c @@ -95,7 +95,15 @@ int x264_pthread_mutex_lock( x264_pthread_mutex_t *mutex ) { static const x264_pthread_mutex_t init = X264_PTHREAD_MUTEX_INITIALIZER; if( !memcmp( mutex, &init, sizeof(x264_pthread_mutex_t) ) ) - *mutex = static_mutex; + { + int ret = 0; + EnterCriticalSection( &static_mutex ); + if( !memcmp( mutex, &init, sizeof(x264_pthread_mutex_t) ) ) + ret = x264_pthread_mutex_init( mutex, NULL ); + LeaveCriticalSection( &static_mutex ); + if( ret ) + return ret; + } EnterCriticalSection( mutex ); return 0; }