Nikolay Sivov : rtworkq: Add RtwqCreateAsyncResult().
Alexandre Julliard
julliard at winehq.org
Wed Feb 5 16:53:34 CST 2020
Module: wine
Branch: master
Commit: fa420eddba89a181e61eaeb4b94cd9d339d0f70c
URL: https://source.winehq.org/git/wine.git/?a=commit;h=fa420eddba89a181e61eaeb4b94cd9d339d0f70c
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Feb 5 08:44:06 2020 +0300
rtworkq: Add RtwqCreateAsyncResult().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/rtworkq/Makefile.in | 3 +
dlls/rtworkq/queue.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++
dlls/rtworkq/rtworkq.spec | 6 +-
include/Makefile.in | 1 +
include/rtworkq.idl | 62 +++++++++++++
5 files changed, 288 insertions(+), 3 deletions(-)
diff --git a/dlls/rtworkq/Makefile.in b/dlls/rtworkq/Makefile.in
index d6d7d6f715..a224198986 100644
--- a/dlls/rtworkq/Makefile.in
+++ b/dlls/rtworkq/Makefile.in
@@ -2,3 +2,6 @@ MODULE = rtworkq.dll
IMPORTLIB = rtworkq
EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ queue.c
diff --git a/dlls/rtworkq/queue.c b/dlls/rtworkq/queue.c
new file mode 100644
index 0000000000..7897ef5dc9
--- /dev/null
+++ b/dlls/rtworkq/queue.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2019-2020 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "initguid.h"
+#include "rtworkq.h"
+#include "wine/debug.h"
+#include "wine/heap.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+
+static LONG platform_lock;
+
+struct async_result
+{
+ RTWQASYNCRESULT result;
+ LONG refcount;
+ IUnknown *object;
+ IUnknown *state;
+};
+
+static struct async_result *impl_from_IRtwqAsyncResult(IRtwqAsyncResult *iface)
+{
+ return CONTAINING_RECORD(iface, struct async_result, result.AsyncResult);
+}
+
+static HRESULT WINAPI async_result_QueryInterface(IRtwqAsyncResult *iface, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+ if (IsEqualIID(riid, &IID_IRtwqAsyncResult) ||
+ IsEqualIID(riid, &IID_IUnknown))
+ {
+ *obj = iface;
+ IRtwqAsyncResult_AddRef(iface);
+ return S_OK;
+ }
+
+ *obj = NULL;
+ WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI async_result_AddRef(IRtwqAsyncResult *iface)
+{
+ struct async_result *result = impl_from_IRtwqAsyncResult(iface);
+ ULONG refcount = InterlockedIncrement(&result->refcount);
+
+ TRACE("%p, %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI async_result_Release(IRtwqAsyncResult *iface)
+{
+ struct async_result *result = impl_from_IRtwqAsyncResult(iface);
+ ULONG refcount = InterlockedDecrement(&result->refcount);
+
+ TRACE("%p, %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ if (result->result.pCallback)
+ IRtwqAsyncCallback_Release(result->result.pCallback);
+ if (result->object)
+ IUnknown_Release(result->object);
+ if (result->state)
+ IUnknown_Release(result->state);
+ if (result->result.hEvent)
+ CloseHandle(result->result.hEvent);
+ heap_free(result);
+
+ RtwqUnlockPlatform();
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI async_result_GetState(IRtwqAsyncResult *iface, IUnknown **state)
+{
+ struct async_result *result = impl_from_IRtwqAsyncResult(iface);
+
+ TRACE("%p, %p.\n", iface, state);
+
+ if (!result->state)
+ return E_POINTER;
+
+ *state = result->state;
+ IUnknown_AddRef(*state);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI async_result_GetStatus(IRtwqAsyncResult *iface)
+{
+ struct async_result *result = impl_from_IRtwqAsyncResult(iface);
+
+ TRACE("%p.\n", iface);
+
+ return result->result.hrStatusResult;
+}
+
+static HRESULT WINAPI async_result_SetStatus(IRtwqAsyncResult *iface, HRESULT status)
+{
+ struct async_result *result = impl_from_IRtwqAsyncResult(iface);
+
+ TRACE("%p, %#x.\n", iface, status);
+
+ result->result.hrStatusResult = status;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI async_result_GetObject(IRtwqAsyncResult *iface, IUnknown **object)
+{
+ struct async_result *result = impl_from_IRtwqAsyncResult(iface);
+
+ TRACE("%p, %p.\n", iface, object);
+
+ if (!result->object)
+ return E_POINTER;
+
+ *object = result->object;
+ IUnknown_AddRef(*object);
+
+ return S_OK;
+}
+
+static IUnknown * WINAPI async_result_GetStateNoAddRef(IRtwqAsyncResult *iface)
+{
+ struct async_result *result = impl_from_IRtwqAsyncResult(iface);
+
+ TRACE("%p.\n", iface);
+
+ return result->state;
+}
+
+static const IRtwqAsyncResultVtbl async_result_vtbl =
+{
+ async_result_QueryInterface,
+ async_result_AddRef,
+ async_result_Release,
+ async_result_GetState,
+ async_result_GetStatus,
+ async_result_SetStatus,
+ async_result_GetObject,
+ async_result_GetStateNoAddRef,
+};
+
+static HRESULT create_async_result(IUnknown *object, IRtwqAsyncCallback *callback, IUnknown *state, IRtwqAsyncResult **out)
+{
+ struct async_result *result;
+
+ if (!out)
+ return E_INVALIDARG;
+
+ result = heap_alloc_zero(sizeof(*result));
+ if (!result)
+ return E_OUTOFMEMORY;
+
+ RtwqLockPlatform();
+
+ result->result.AsyncResult.lpVtbl = &async_result_vtbl;
+ result->refcount = 1;
+ result->object = object;
+ if (result->object)
+ IUnknown_AddRef(result->object);
+ result->result.pCallback = callback;
+ if (result->result.pCallback)
+ IRtwqAsyncCallback_AddRef(result->result.pCallback);
+ result->state = state;
+ if (result->state)
+ IUnknown_AddRef(result->state);
+
+ *out = &result->result.AsyncResult;
+
+ TRACE("Created async result object %p.\n", *out);
+
+ return S_OK;
+}
+
+HRESULT WINAPI RtwqCreateAsyncResult(IUnknown *object, IRtwqAsyncCallback *callback, IUnknown *state,
+ IRtwqAsyncResult **out)
+{
+ TRACE("%p, %p, %p, %p.\n", object, callback, state, out);
+
+ return create_async_result(object, callback, state, out);
+}
+
+HRESULT WINAPI RtwqLockPlatform(void)
+{
+ InterlockedIncrement(&platform_lock);
+
+ return S_OK;
+}
+
+HRESULT WINAPI RtwqUnlockPlatform(void)
+{
+ InterlockedDecrement(&platform_lock);
+
+ return S_OK;
+}
diff --git a/dlls/rtworkq/rtworkq.spec b/dlls/rtworkq/rtworkq.spec
index 29e56846c6..900aa5f230 100644
--- a/dlls/rtworkq/rtworkq.spec
+++ b/dlls/rtworkq/rtworkq.spec
@@ -6,7 +6,7 @@
@ stub RtwqCancelDeadline
@ stub RtwqCancelMultipleWaitingWorkItem
@ stub RtwqCancelWorkItem
-@ stub RtwqCreateAsyncResult
+@ stdcall RtwqCreateAsyncResult(ptr ptr ptr ptr)
@ stub RtwqEndRegisterWorkQueueWithMMCSS
@ stub RtwqEndUnregisterWorkQueueWithMMCSS
@ stub RtwqGetPlatform
@@ -15,7 +15,7 @@
@ stub RtwqGetWorkQueueMMCSSTaskId
@ stub RtwqInvokeCallback
@ stub RtwqJoinWorkQueue
-@ stub RtwqLockPlatform
+@ stdcall RtwqLockPlatform()
@ stub RtwqLockSharedWorkQueue
@ stub RtwqLockWorkQueue
@ stub RtwqPutMultipleWaitingWorkItem
@@ -31,7 +31,7 @@
@ stub RtwqShutdown
@ stub RtwqStartup
@ stub RtwqUnjoinWorkQueue
-@ stub RtwqUnlockPlatform
+@ stdcall RtwqUnlockPlatform()
@ stub RtwqUnlockWorkQueue
@ stub RtwqUnregisterPlatformEvents
@ stub RtwqUnregisterPlatformFromMMCSS
diff --git a/include/Makefile.in b/include/Makefile.in
index 5f967b616d..a91372eb4d 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -579,6 +579,7 @@ SOURCES = \
rstloc.idl \
rstnot.idl \
rtutils.h \
+ rtworkq.idl \
sal.h \
sapi.idl \
sapiaut.idl \
diff --git a/include/rtworkq.idl b/include/rtworkq.idl
new file mode 100644
index 0000000000..d22b09ca50
--- /dev/null
+++ b/include/rtworkq.idl
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+import "unknwn.idl";
+
+[
+ object,
+ uuid(ac6b7889-0740-4d51-8619-905994a55cc6),
+ local
+]
+interface IRtwqAsyncResult : IUnknown
+{
+ HRESULT GetState([out] IUnknown **state);
+ HRESULT GetStatus();
+ HRESULT SetStatus([in] HRESULT status);
+ HRESULT GetObject([out] IUnknown **object);
+ IUnknown *GetStateNoAddRef();
+}
+
+[
+ object,
+ uuid(a27003cf-2354-4f2a-8d6a-ab7cff15437e),
+ local
+]
+interface IRtwqAsyncCallback : IUnknown
+{
+ HRESULT GetParameters([out] DWORD *flags, [out] DWORD *queue);
+ HRESULT Invoke([in] IRtwqAsyncResult *result);
+}
+
+cpp_quote("#ifdef __WINESRC__")
+cpp_quote("typedef struct tagRTWQASYNCRESULT")
+cpp_quote("{")
+cpp_quote(" IRtwqAsyncResult AsyncResult;")
+cpp_quote("#else")
+cpp_quote("typedef struct tagRTWQASYNCRESULT : public IRtwqAsyncResult {")
+cpp_quote("#endif")
+cpp_quote(" OVERLAPPED overlapped;")
+cpp_quote(" IRtwqAsyncCallback *pCallback;")
+cpp_quote(" HRESULT hrStatusResult;")
+cpp_quote(" DWORD dwBytesTransferred;")
+cpp_quote(" HANDLE hEvent;")
+cpp_quote("} RTWQASYNCRESULT;")
+
+cpp_quote("HRESULT WINAPI RtwqCreateAsyncResult(IUnknown *object, IRtwqAsyncCallback *callback, IUnknown *state, IRtwqAsyncResult **result);")
+cpp_quote("HRESULT WINAPI RtwqLockPlatform(void);")
+cpp_quote("HRESULT WINAPI RtwqUnlockPlatform(void);")
More information about the wine-cvs
mailing list