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