[PATCH 2/3] dpnet: IDirectPlay8ThreadPool is a singleton interface.
Alistair Leslie-Hughes
leslie_alistair at hotmail.com
Fri Nov 11 01:02:35 CST 2016
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
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
More information about the wine-patches
mailing list