Signed-off-by: Nikolay Sivov nsivov@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);")