]> granicus.if.org Git - libx264/commitdiff
Fix thread safety of x264_threading_init() and use of X264_PTHREAD_MUTEX_INITIALIZER...
authorAnton Mitrofanov <BugMaster@narod.ru>
Fri, 22 Sep 2017 14:05:06 +0000 (17:05 +0300)
committerAnton Mitrofanov <BugMaster@narod.ru>
Sun, 24 Dec 2017 20:47:25 +0000 (23:47 +0300)
common/osdep.c
common/threadpool.c
common/win32thread.c

index a8cf1d7cd1c50240d92755d806f6ea3740e2d5c7..deb546ea983ad7eaad9b896dc44b1c061eb565c3 100644 (file)
@@ -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
index 61d75ce0c6516c956825bc965cdb8f30c537186a..f707cfdd98b7a900955d825151485a5e05237bfb 100644 (file)
@@ -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;
index d12f16e7e6c4f680bc35c7cd029d25e1f97ad713..3b71078a2103f0aaaf6a7417c4347fdc5ad15512 100644 (file)
@@ -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;
 }