[x264-devel] Fix thread safety of x264_threading_init() and use of X264_PTHREAD_MUTEX_INITIALIZER with win32thread

Anton Mitrofanov git at videolan.org
Mon Dec 25 20:39:52 CET 2017


x264 | branch: master | Anton Mitrofanov <BugMaster at 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;
 }



More information about the x264-devel mailing list