wined3d: Make CreateFakeGLContext thread safe. [try 2]

Jan Zerebecki jan.wine at zerebecki.de
Wed Jan 3 07:52:08 CST 2007


Should be race free now.

This adds thread safety to CreateFakeGLContext and it's
corresponding Release function only. This addresses no thread
safety in the rest of wined3d, which AFAIk as a whole is still
not thread safe. When addressing thread safety in wined3d it must
also be taken care that a GL context is not deleted away by a
different thread when execution is between these two functions.

If this patch is rejected from inclusion, please tell me why, as
I would have to ask anyway.

From: Jan Zerebecki <jan.wine at zerebecki.de>
Changelog:
wined3d: Make CreateFakeGLContext thread safe.
---

 dlls/wined3d/directx.c |   23 ++++++++++++++++++++---
 1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 17ad687..c405e8b 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -78,11 +78,24 @@ static BOOL            wined3d_fake_gl_c
 static BOOL            wined3d_fake_gl_context_available = FALSE;
 static Display*        wined3d_fake_gl_context_display = NULL;
 
+static CRITICAL_SECTION wined3d_fake_gl_context_cs;
+static CRITICAL_SECTION_DEBUG wined3d_fake_gl_context_cs_debug =
+{
+    0, 0, &wined3d_fake_gl_context_cs,
+    { &wined3d_fake_gl_context_cs_debug.ProcessLocksList,
+      &wined3d_fake_gl_context_cs_debug.ProcessLocksList },
+    0, 0, { (DWORD_PTR)(__FILE__ ": wined3d_fake_gl_context_cs") }
+};
+static CRITICAL_SECTION wined3d_fake_gl_context_cs = { &wined3d_fake_gl_context_cs_debug, -1, 0, 0, 0, 0 };
+
 static void WineD3D_ReleaseFakeGLContext(void) {
     GLXContext glCtx;
 
+    EnterCriticalSection(&wined3d_fake_gl_context_cs);
+
     if(!wined3d_fake_gl_context_available) {
         TRACE_(d3d_caps)("context not available\n");
+        LeaveCriticalSection(&wined3d_fake_gl_context_cs);
         return;
     }
 
@@ -95,17 +108,21 @@ static void WineD3D_ReleaseFakeGLContext
             glXMakeCurrent(wined3d_fake_gl_context_display, None, NULL);
             glXDestroyContext(wined3d_fake_gl_context_display, glCtx);
         }
-        LEAVE_GL();
         wined3d_fake_gl_context_available = FALSE;
     }
     assert(wined3d_fake_gl_context_ref >= 0);
 
+    LeaveCriticalSection(&wined3d_fake_gl_context_cs);
+    LEAVE_GL();
 }
 
 static BOOL WineD3D_CreateFakeGLContext(void) {
     XVisualInfo* visInfo;
     GLXContext   glCtx;
 
+    ENTER_GL();
+    EnterCriticalSection(&wined3d_fake_gl_context_cs);
+
     TRACE_(d3d_caps)("getting context...\n");
     if(wined3d_fake_gl_context_ref > 0) goto ret;
     assert(0 == wined3d_fake_gl_context_ref);
@@ -119,8 +136,6 @@ static BOOL WineD3D_CreateFakeGLContext(
         ReleaseDC(0, device_context);
     }
 
-    ENTER_GL();
-
     visInfo = NULL;
     glCtx = glXGetCurrentContext();
 
@@ -170,11 +185,13 @@ static BOOL WineD3D_CreateFakeGLContext(
     TRACE_(d3d_caps)("incrementing ref from %i\n", wined3d_fake_gl_context_ref);
     wined3d_fake_gl_context_ref++;
     wined3d_fake_gl_context_available = TRUE;
+    LeaveCriticalSection(&wined3d_fake_gl_context_cs);
     return TRUE;
   fail:
     if(visInfo) XFree(visInfo);
     if(glCtx) glXDestroyContext(wined3d_fake_gl_context_display, glCtx);
     LEAVE_GL();
+    LeaveCriticalSection(&wined3d_fake_gl_context_cs);
     return FALSE;
 }
 



More information about the wine-patches mailing list