glapi: Protect _glapi_check_multithread by a mutex.
authorChia-I Wu <olvaffe@gmail.com>
Fri, 10 Jul 2009 07:21:42 +0000 (15:21 +0800)
committerBrian Paul <brianp@vmware.com>
Mon, 24 Aug 2009 17:45:57 +0000 (11:45 -0600)
Multiple threads might call _glapi_check_multithread at roughly the same
time.  It is possbile that all of them are wrongly regarded as firstCall
if there is no mutex.  This bug causes xeglthreads to crash sometimes.

Acked-by: Ian Romanick <ian.d.romanick@intel.com>
Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
src/mesa/glapi/glapi.c

index 2b105d0f17ddda1cbf9b295901839fc70173d4ce..30aec209e7dc7301394c2b72a72a581714d95a0f 100644 (file)
@@ -198,6 +198,7 @@ PUBLIC const void *_glapi_Context = NULL;
 
 #if defined(THREADS)
 
+_glthread_DECLARE_STATIC_MUTEX(ThreadCheckMutex);
 static GLboolean ThreadSafe = GL_FALSE;  /**< In thread-safe mode? */
 _glthread_TSD _gl_DispatchTSD;           /**< Per-thread dispatch pointer */
 static _glthread_TSD ContextTSD;         /**< Per-thread context pointer */
@@ -231,23 +232,23 @@ void
 _glapi_check_multithread(void)
 {
 #if defined(THREADS) && !defined(GLX_USE_TLS)
-   if (!ThreadSafe) {
-      static unsigned long knownID;
-      static GLboolean firstCall = GL_TRUE;
-      if (firstCall) {
-         knownID = _glthread_GetID();
-         firstCall = GL_FALSE;
-      }
-      else if (knownID != _glthread_GetID()) {
-         ThreadSafe = GL_TRUE;
-         _glapi_set_dispatch(NULL);
-         _glapi_set_context(NULL);
-      }
+   static unsigned long knownID;
+   static GLboolean firstCall = GL_TRUE;
+
+   if (ThreadSafe)
+      return;
+
+   _glthread_LOCK_MUTEX(ThreadCheckMutex);
+   if (firstCall) {
+      knownID = _glthread_GetID();
+      firstCall = GL_FALSE;
    }
-   else if (!_glapi_get_dispatch()) {
-      /* make sure that this thread's dispatch pointer isn't null */
+   else if (knownID != _glthread_GetID()) {
+      ThreadSafe = GL_TRUE;
       _glapi_set_dispatch(NULL);
+      _glapi_set_context(NULL);
    }
+   _glthread_UNLOCK_MUTEX(ThreadCheckMutex);
 #endif
 }