From: Alistair Leslie-Hughes Subject: [PATCH 2/3] dpnet: IDirectPlay8ThreadPool is a singleton interface. Message-Id: Date: Fri, 11 Nov 2016 07:02:35 +0000 In-Reply-To: <20161111070158.8684-1-leslie_alistair@hotmail.com> References: <20161111070158.8684-1-leslie_alistair@hotmail.com> Signed-off-by: Alistair Leslie-Hughes --- dlls/dpnet/dpnet_main.c | 1 + dlls/dpnet/dpnet_private.h | 6 ++--- dlls/dpnet/threadpool.c | 58 ++++++++++++++++++++++++++++------------------ 3 files changed, 39 insertions(+), 26 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 dee1654..41313d1 100644 --- a/dlls/dpnet/dpnet_private.h +++ b/dlls/dpnet/dpnet_private.h @@ -124,8 +124,7 @@ struct IDirectPlay8LobbiedApplicationImpl */ struct IDirectPlay8ThreadPoolImpl { - IDirectPlay8ThreadPool IDirectPlay8ThreadPool_iface; - LONG ref; + IDirectPlay8ThreadPool IDirectPlay8ThreadPool_iface; }; /** @@ -136,11 +135,12 @@ extern HRESULT DPNET_CreateDirectPlay8Server(LPCLASSFACTORY iface, LPUNKNOWN pun extern HRESULT DPNET_CreateDirectPlay8Peer(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj) DECLSPEC_HIDDEN; extern HRESULT DPNET_CreateDirectPlay8Address(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj) DECLSPEC_HIDDEN; extern HRESULT DPNET_CreateDirectPlay8LobbiedApp(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj) DECLSPEC_HIDDEN; -extern HRESULT DPNET_CreateDirectPlay8ThreadPool(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj) DECLSPEC_HIDDEN; +extern HRESULT DPNET_CreateDirectPlay8ThreadPool(IClassFactory *iface, LPUNKNOWN punkOuter, REFIID riid, void **ppobj) DECLSPEC_HIDDEN; extern HRESULT DPNET_CreateDirectPlay8LobbyClient(IClassFactory *iface, IUnknown *pUnkOuter, REFIID riid, void **ppobj) DECLSPEC_HIDDEN; extern void init_dpn_sp_caps(DPN_SP_CAPS *dpnspcaps) DECLSPEC_HIDDEN; extern void init_winsock(void) DECLSPEC_HIDDEN; +extern void release_threadpool(void) DECLSPEC_HIDDEN; /* used for generic dumping (copied from ddraw) */ typedef struct { diff --git a/dlls/dpnet/threadpool.c b/dlls/dpnet/threadpool.c index 274789d..3ce9731 100644 --- a/dlls/dpnet/threadpool.c +++ b/dlls/dpnet/threadpool.c @@ -37,6 +37,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); @@ -62,21 +64,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 1; } 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 2; } /* IDirectPlay8ThreadPool interface follows */ @@ -133,22 +126,41 @@ 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; + + 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); } -- 2.10.2