Nikolay Sivov : rtworkq: Add RtwqAllocateWorkQueue().
Alexandre Julliard
julliard at winehq.org
Wed Feb 5 16:53:34 CST 2020
Module: wine
Branch: master
Commit: 0c91600efb750855d75574a338d30c6cadb01624
URL: https://source.winehq.org/git/wine.git/?a=commit;h=0c91600efb750855d75574a338d30c6cadb01624
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Feb 5 08:44:12 2020 +0300
rtworkq: Add RtwqAllocateWorkQueue().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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);")
More information about the wine-cvs
mailing list