[PATCH] dpnet: IDirectPlay8ThreadPool is a singleton interface.

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Fri Feb 17 00:43:01 CST 2017


Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
 dlls/dpnet/dpnet_main.c    |  1 +
 dlls/dpnet/dpnet_private.h |  2 +-
 dlls/dpnet/tests/thread.c  |  6 ++---
 dlls/dpnet/threadpool.c    | 61 +++++++++++++++++++++++++++++-----------------
 4 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/dlls/dpnet/dpnet_main.c b/dlls/dpnet/dpnet_main.c
index cc80ebc..ffa7aae 100644
--- a/dlls/dpnet/dpnet_main.c
+++ b/dlls/dpnet/dpnet_main.c
@@ -77,6 +77,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
             if (lpvReserved) break;
             if(winsock_loaded)
                 WSACleanup();
+            release_threadpool();
             break;
     }
     return TRUE;
diff --git a/dlls/dpnet/dpnet_private.h b/dlls/dpnet/dpnet_private.h
index 7b6de4a..013bca7 100644
--- a/dlls/dpnet/dpnet_private.h
+++ b/dlls/dpnet/dpnet_private.h
@@ -121,7 +121,6 @@ struct IDirectPlay8LobbiedApplicationImpl
 struct IDirectPlay8ThreadPoolImpl
 {
     IDirectPlay8ThreadPool IDirectPlay8ThreadPool_iface;
-    LONG ref;
 
     PFNDPNMESSAGEHANDLER msghandler;
     DWORD flags;
@@ -143,6 +142,7 @@ extern void init_dpn_sp_caps(DPN_SP_CAPS *dpnspcaps) DECLSPEC_HIDDEN;
 extern void init_winsock(void) DECLSPEC_HIDDEN;
 extern HRESULT enum_services_providers(const GUID * const service, DPN_SERVICE_PROVIDER_INFO * const info_buffer,
         DWORD * const buf_size, DWORD * const returned) DECLSPEC_HIDDEN;
+extern void release_threadpool(void) DECLSPEC_HIDDEN;
 
 /* used for generic dumping (copied from ddraw) */
 typedef struct {
diff --git a/dlls/dpnet/tests/thread.c b/dlls/dpnet/tests/thread.c
index 7129739..80a7ce5 100644
--- a/dlls/dpnet/tests/thread.c
+++ b/dlls/dpnet/tests/thread.c
@@ -70,7 +70,7 @@ static void create_threadpool(void)
     ok(hr == S_OK, "got 0x%08x\n", hr);
 
     hr = IDirectPlay8ThreadPool_Initialize(pool2, NULL, &DirectPlayThreadHandler, 0);
-    todo_wine ok(hr == DPNERR_ALREADYINITIALIZED, "got 0x%08x\n", hr);
+    ok(hr == DPNERR_ALREADYINITIALIZED, "got 0x%08x\n", hr);
 
     hr = IDirectPlay8ThreadPool_GetThreadCount(pool1, -1, &threadcnt, 0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
@@ -219,13 +219,13 @@ static void test_singleton(void)
 
     hr = CoCreateInstance( &CLSID_DirectPlay8ThreadPool, NULL, CLSCTX_ALL, &IID_IDirectPlay8ThreadPool, (void**)&pool2);
     ok(hr == S_OK, "got 0x%08x\n", hr);
-    ok(pool1 != pool2, "same pointer returned.\n");
+    todo_wine ok(pool1 != pool2, "same pointer returned.\n");
 
     hr = IDirectPlay8ThreadPool_Initialize(pool1, NULL, &DirectPlayThreadHandler, 0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
 
     hr = IDirectPlay8ThreadPool_Initialize(pool2, NULL, &DirectPlayThreadHandler, 0);
-    todo_wine ok(hr == DPNERR_ALREADYINITIALIZED, "got 0x%08x\n", hr);
+    ok(hr == DPNERR_ALREADYINITIALIZED, "got 0x%08x\n", hr);
 
     hr = IDirectPlay8ThreadPool_Close(pool1, 0);
     ok(hr == S_OK, "got 0x%08x\n", hr);
diff --git a/dlls/dpnet/threadpool.c b/dlls/dpnet/threadpool.c
index 37a05e2..c6b59f4 100644
--- a/dlls/dpnet/threadpool.c
+++ b/dlls/dpnet/threadpool.c
@@ -36,6 +36,8 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dpnet);
 
+static IDirectPlay8ThreadPool *threadpool = NULL;
+
 static inline IDirectPlay8ThreadPoolImpl *impl_from_IDirectPlay8ThreadPool(IDirectPlay8ThreadPool *iface)
 {
     return CONTAINING_RECORD(iface, IDirectPlay8ThreadPoolImpl, IDirectPlay8ThreadPool_iface);
@@ -61,21 +63,12 @@ static HRESULT WINAPI IDirectPlay8ThreadPoolImpl_QueryInterface(IDirectPlay8Thre
 
 static ULONG WINAPI IDirectPlay8ThreadPoolImpl_AddRef(IDirectPlay8ThreadPool *iface)
 {
-    IDirectPlay8ThreadPoolImpl* This = impl_from_IDirectPlay8ThreadPool(iface);
-    ULONG RefCount = InterlockedIncrement(&This->ref);
-
-    return RefCount;
+    return 2;
 }
 
 static ULONG WINAPI IDirectPlay8ThreadPoolImpl_Release(IDirectPlay8ThreadPool *iface)
 {
-    IDirectPlay8ThreadPoolImpl* This = impl_from_IDirectPlay8ThreadPool(iface);
-    ULONG RefCount = InterlockedDecrement(&This->ref);
-
-    if(!RefCount)
-        HeapFree(GetProcessHeap(), 0, This);
-
-    return RefCount;
+    return 1;
 }
 
 /* IDirectPlay8ThreadPool interface follows */
@@ -151,22 +144,44 @@ static const IDirectPlay8ThreadPoolVtbl DirectPlay8ThreadPool_Vtbl =
     IDirectPlay8ThreadPoolImpl_DoWork
 };
 
-HRESULT DPNET_CreateDirectPlay8ThreadPool(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj)
+static IDirectPlay8ThreadPool *get_threadpool(void)
 {
-    IDirectPlay8ThreadPoolImpl* Client;
+    if (!threadpool)
+    {
+        IDirectPlay8ThreadPoolImpl *obj;
 
-    Client = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectPlay8ThreadPoolImpl));
+        obj = heap_alloc(sizeof(IDirectPlay8ThreadPoolImpl));
+        if (!obj)
+            return NULL;
 
-    if(Client == NULL)
-    {
-        *ppobj = NULL;
-        WARN("Not enough memory\n");
-        return E_OUTOFMEMORY;
+        obj->IDirectPlay8ThreadPool_iface.lpVtbl = &DirectPlay8ThreadPool_Vtbl;
+        obj->msghandler  = NULL;
+        obj->flags       = 0;
+        obj->usercontext = NULL;
+
+        if (InterlockedCompareExchangePointer((void**)&threadpool, &obj->IDirectPlay8ThreadPool_iface, NULL))
+            HeapFree(GetProcessHeap(), 0, obj);
+        else
+            TRACE("Created the threadpool at %p\n", obj);
     }
 
-    Client->IDirectPlay8ThreadPool_iface.lpVtbl = &DirectPlay8ThreadPool_Vtbl;
-    Client->ref = 0;
+    return threadpool;
+}
 
-    return IDirectPlay8ThreadPoolImpl_QueryInterface(&Client->IDirectPlay8ThreadPool_iface, riid,
-            ppobj);
+void release_threadpool(void)
+{
+    IDirectPlay8ThreadPoolImpl *pool;
+
+    if (!threadpool)
+        return;
+
+    pool = impl_from_IDirectPlay8ThreadPool(threadpool);
+
+    heap_free(pool);
+}
+
+HRESULT DPNET_CreateDirectPlay8ThreadPool(IClassFactory *iface, LPUNKNOWN punkOuter, REFIID riid, void **obj)
+{
+    IDirectPlay8ThreadPool *pool = get_threadpool();
+    return IDirectPlay8ThreadPool_QueryInterface(pool, riid, obj);
 }
-- 
1.9.1




More information about the wine-patches mailing list