DDraw: Protect the ddraw list with a critical section

Stefan Dösinger stefandoesinger at gmx.at
Sun Aug 27 03:57:46 CDT 2006


This patch adds a critical section for the global ddraw object list. This is 
done onconditionally, no matter if the application specifies the 
DDSCL_MULTITHREADED flag, because there can be multiple ddraw objects created 
at the same time from different threads.
-------------- next part --------------
From nobody Mon Sep 17 00:00:00 2001
From: Stefan Dösinger <stefan at codeweavers.com>
Date: Sun Aug 27 10:28:33 2006 +0200
Subject: [PATCH] DDraw: Protect the ddraw object list

---

 dlls/ddraw/ddraw.c         |    3 +++
 dlls/ddraw/ddraw_private.h |    1 +
 dlls/ddraw/main.c          |   13 +++++++++++++
 3 files changed, 17 insertions(+), 0 deletions(-)

2542eb9f1ebf9d071830b5e0926a4302e106d7bc
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 44fe5a0..f33f5f1 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -64,6 +64,7 @@ static const DDDEVICEIDENTIFIER2 devicei
 
 /* This is for cleanup if a broken app doesn't Release its objects */
 IDirectDrawImpl *ddraw_list;
+CRITICAL_SECTION listCrit;
 
 /*****************************************************************************
  * IUnknown Methods
@@ -263,6 +264,7 @@ IDirectDrawImpl_Destroy(IDirectDrawImpl 
     UnregisterClassA(This->classname, 0);
 
     /* Unchain it from the ddraw list */
+    EnterCriticalSection(&listCrit);
     if(ddraw_list == This)
     {
         ddraw_list = This->next;
@@ -278,6 +280,7 @@ IDirectDrawImpl_Destroy(IDirectDrawImpl 
         else
             ERR("Didn't find the previous ddraw element in the list\n");
     }
+    LeaveCriticalSection(&listCrit);
 
     /* Release the attached WineD3D stuff */
     IWineD3DDevice_Release(This->wineD3DDevice);
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 5cf9312..abb6e36 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -184,6 +184,7 @@ IDirectDrawImpl_RecreateSurfacesCallback
                                          void *Context);
 /* The cleanup list */
 extern IDirectDrawImpl *ddraw_list;
+extern CRITICAL_SECTION listCrit;
 
 /* The default surface type */
 extern WINED3DSURFTYPE DefaultSurfaceType;
diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
index 8aab95c..1084c01 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -301,8 +301,10 @@ DDRAW_Create(GUID *guid,
 #undef FX_CAPS
 
     /* Add the object to the ddraw cleanup list */
+    EnterCriticalSection(&listCrit);
     This->next = ddraw_list;
     ddraw_list = This;
+    LeaveCriticalSection(&listCrit);
 
     /* Call QueryInterface to get the pointer to the requested interface. This also initializes
      * The required refcount
@@ -849,6 +851,13 @@ DllMain(HINSTANCE hInstDLL,
             }
         }
 
+        /* Initialize the ddraw object list critical section unconditionally
+         * Even if the app doesn't use multithreaded ddraw objects it can still
+         * use multiple ddraw objects in multiple threads
+         * Well, initialize it only once
+         */
+        if(counter == 0) InitializeCriticalSection(&listCrit);
+
         DisableThreadLibraryCalls(hInstDLL);
         TRACE("Attach counter: %ld\n", InterlockedIncrement(&counter));
     }
@@ -858,6 +867,9 @@ DllMain(HINSTANCE hInstDLL,
 
         if(counter == 0)
         {
+            /* I don'T have to lock the list here, because this code is only called for the last
+             * process beeing detached, so no threads will interfere
+             */
             if(ddraw_list)
             {
                 IDirectDrawImpl *ddraw;
@@ -916,6 +928,7 @@ DllMain(HINSTANCE hInstDLL,
                     while(IDirectDraw7_Release(ICOM_INTERFACE(ddraw, IDirectDraw7)));
                 }
             }
+            DeleteCriticalSection(&listCrit);
         }
     }
 
-- 
1.2.4



More information about the wine-patches mailing list