[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