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