DDraw: Protect the ddraw object list

Stefan Dösinger stefandoesinger at gmx.at
Thu Oct 5 14:56:29 CDT 2006


This is a resend of the patch sent a few weeks ago as requested by Alexandre. 
It protects the global ddraw object list with a critical section.
-------------- next part --------------
From 39e696682d1edf6437bd55bf7d4e6df46b8c319e Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan_D=F6singer?= <stefan at codeweavers.com>
Date: Sun, 27 Aug 2006 10:28:33 +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(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 333fcde..50b6738 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 bdb8b31..00ad213 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -303,8 +303,10 @@ #undef CKEY_CAPS
 #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
@@ -851,6 +853,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));
     }
@@ -860,6 +869,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;
@@ -918,6 +930,7 @@ DllMain(HINSTANCE hInstDLL,
                     while(IDirectDraw7_Release(ICOM_INTERFACE(ddraw, IDirectDraw7)));
                 }
             }
+            DeleteCriticalSection(&listCrit);
         }
     }
 
-- 
1.4.1.1



More information about the wine-patches mailing list