Discussion:
Fix thread safety of x264_threading_init() and use of X264_PTHREAD_MUTEX_INITIALIZER with win32thread
(too old to reply)
Anton Mitrofanov
2017-12-25 19:39:52 UTC
Permalink
Raw Message
x264 | branch: master | Anton Mitrofanov <***@narod.ru> | Fri Sep 22 17:05:06 2017 +0300| [fefc3fa1fa98a7bac4eaf3c8e6e1c52b7e427ddd] | committer: Anton Mitrofanov

Fix thread safety of x264_threading_init() and use of X264_PTHREAD_MUTEX_INITIALIZER with win32thread
http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=fefc3fa1fa98a7bac4eaf3c8e6e1c52b7e427ddd
---

common/osdep.c | 22 ++++++++++++++++++----
common/threadpool.c | 3 +++
common/win32thread.c | 10 +++++++++-
3 files changed, 30 insertions(+), 5 deletions(-)

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;
}

Loading...