[PATCH 8/9] rtworkq: Add RtwqAllocateWorkQueue().

Nikolay Sivov nsivov at codeweavers.com
Tue Feb 4 23:44:12 CST 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/rtworkq/queue.c      | 59 +++++++++++++++++++++++++++++++++++++++
 dlls/rtworkq/rtworkq.spec |  4 +--
 include/rtworkq.idl       |  2 ++
 3 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/dlls/rtworkq/queue.c b/dlls/rtworkq/queue.c
index 16411bfc49..a6aac6abda 100644
--- a/dlls/rtworkq/queue.c
+++ b/dlls/rtworkq/queue.c
@@ -54,6 +54,8 @@ struct queue_handle
 
 static struct queue_handle user_queues[MAX_USER_QUEUE_HANDLES];
 static struct queue_handle *next_free_user_queue;
+static struct queue_handle *next_unused_user_queue = user_queues;
+static WORD queue_generation;
 
 static CRITICAL_SECTION queues_section;
 static CRITICAL_SECTION_DEBUG queues_critsect_debug =
@@ -559,6 +561,49 @@ static HRESULT queue_cancel_item(struct queue *queue, RTWQWORKITEM_KEY key)
     return hr;
 }
 
+static HRESULT alloc_user_queue(RTWQ_WORKQUEUE_TYPE queue_type, DWORD *queue_id)
+{
+    struct queue_handle *entry;
+    struct queue *queue;
+    unsigned int idx;
+
+    *queue_id = RTWQ_CALLBACK_QUEUE_UNDEFINED;
+
+    if (platform_lock <= 0)
+        return RTWQ_E_SHUTDOWN;
+
+    queue = heap_alloc_zero(sizeof(*queue));
+    if (!queue)
+        return E_OUTOFMEMORY;
+    init_work_queue(queue_type, queue);
+
+    EnterCriticalSection(&queues_section);
+
+    entry = next_free_user_queue;
+    if (entry)
+        next_free_user_queue = entry->obj;
+    else if (next_unused_user_queue < user_queues + MAX_USER_QUEUE_HANDLES)
+        entry = next_unused_user_queue++;
+    else
+    {
+        LeaveCriticalSection(&queues_section);
+        heap_free(queue);
+        WARN("Out of user queue handles.\n");
+        return E_OUTOFMEMORY;
+    }
+
+    entry->refcount = 1;
+    entry->obj = queue;
+    if (++queue_generation == 0xffff) queue_generation = 1;
+    entry->generation = queue_generation;
+    idx = entry - user_queues + FIRST_USER_QUEUE_HANDLE;
+    *queue_id = (idx << 16) | entry->generation;
+
+    LeaveCriticalSection(&queues_section);
+
+    return S_OK;
+}
+
 struct async_result
 {
     RTWQASYNCRESULT result;
@@ -999,6 +1044,20 @@ HRESULT WINAPI RtwqInvokeCallback(IRtwqAsyncResult *result)
     return invoke_async_callback(result);
 }
 
+HRESULT WINAPI RtwqPutWorkItem(DWORD queue, LONG priority, IRtwqAsyncResult *result)
+{
+    TRACE("%d, %d, %p.\n", queue, priority, result);
+
+    return queue_put_work_item(queue, priority, result);
+}
+
+HRESULT WINAPI RtwqAllocateWorkQueue(RTWQ_WORKQUEUE_TYPE queue_type, DWORD *queue)
+{
+    TRACE("%d, %p.\n", queue_type, queue);
+
+    return alloc_user_queue(queue_type, queue);
+}
+
 HRESULT WINAPI RtwqLockWorkQueue(DWORD queue)
 {
     TRACE("%#x.\n", queue);
diff --git a/dlls/rtworkq/rtworkq.spec b/dlls/rtworkq/rtworkq.spec
index 8846047d46..48bc17cbfc 100644
--- a/dlls/rtworkq/rtworkq.spec
+++ b/dlls/rtworkq/rtworkq.spec
@@ -1,6 +1,6 @@
 @ stdcall RtwqAddPeriodicCallback(ptr ptr ptr)
 @ stub RtwqAllocateSerialWorkQueue
-@ stub RtwqAllocateWorkQueue
+@ stdcall RtwqAllocateWorkQueue(long ptr)
 @ stub RtwqBeginRegisterWorkQueueWithMMCSS
 @ stub RtwqBeginUnregisterWorkQueueWithMMCSS
 @ stub RtwqCancelDeadline
@@ -20,7 +20,7 @@
 @ stdcall RtwqLockWorkQueue(long)
 @ stub RtwqPutMultipleWaitingWorkItem
 @ stdcall RtwqPutWaitingWorkItem(long long ptr ptr)
-@ stub RtwqPutWorkItem
+@ stdcall RtwqPutWorkItem(long long ptr)
 @ stub RtwqRegisterPlatformEvents
 @ stub RtwqRegisterPlatformWithMMCSS
 @ stdcall RtwqRemovePeriodicCallback(long)
diff --git a/include/rtworkq.idl b/include/rtworkq.idl
index 3c167460c8..001cf2c3e9 100644
--- a/include/rtworkq.idl
+++ b/include/rtworkq.idl
@@ -78,12 +78,14 @@ cpp_quote("} RTWQASYNCRESULT;")
 cpp_quote("typedef void (WINAPI *RTWQPERIODICCALLBACK)(IUnknown *context);")
 
 cpp_quote("HRESULT WINAPI RtwqAddPeriodicCallback(RTWQPERIODICCALLBACK callback, IUnknown *context, DWORD *key);")
+cpp_quote("HRESULT WINAPI RtwqAllocateWorkQueue(RTWQ_WORKQUEUE_TYPE queue_type, DWORD *queue);")
 cpp_quote("HRESULT WINAPI RtwqCancelWorkItem(RTWQWORKITEM_KEY key);")
 cpp_quote("HRESULT WINAPI RtwqCreateAsyncResult(IUnknown *object, IRtwqAsyncCallback *callback, IUnknown *state, IRtwqAsyncResult **result);")
 cpp_quote("HRESULT WINAPI RtwqInvokeCallback(IRtwqAsyncResult *result);")
 cpp_quote("HRESULT WINAPI RtwqLockPlatform(void);")
 cpp_quote("HRESULT WINAPI RtwqLockWorkQueue(DWORD queue);")
 cpp_quote("HRESULT WINAPI RtwqPutWaitingWorkItem(HANDLE event, LONG priority, IRtwqAsyncResult *result, RTWQWORKITEM_KEY *key);")
+cpp_quote("HRESULT WINAPI RtwqPutWorkItem(DWORD queue, LONG priority, IRtwqAsyncResult *result);")
 cpp_quote("HRESULT WINAPI RtwqRemovePeriodicCallback(DWORD key);")
 cpp_quote("HRESULT WINAPI RtwqScheduleWorkItem(IRtwqAsyncResult *result, INT64 timeout, RTWQWORKITEM_KEY *key);")
 cpp_quote("HRESULT WINAPI RtwqShutdown(void);")
-- 
2.24.1




More information about the wine-devel mailing list