[PATCH] rtworkq: Partially implement shared queues.

Nikolay Sivov nsivov at codeweavers.com
Thu Mar 25 11:06:19 CDT 2021


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfplat/mfplat.spec    |  1 +
 dlls/mfplat/tests/mfplat.c | 46 ++++++++++++++++++++++++++++++++++++++
 dlls/rtworkq/queue.c       | 34 ++++++++++++++++++++++++++--
 include/mfapi.h            |  1 +
 4 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
index 7d014e334c8..cbda9404aa9 100644
--- a/dlls/mfplat/mfplat.spec
+++ b/dlls/mfplat/mfplat.spec
@@ -132,6 +132,7 @@
 @ stub MFJoinIoPort
 @ stdcall MFJoinWorkQueue(long long ptr) rtworkq.RtwqJoinWorkQueue
 @ stdcall MFLockPlatform() rtworkq.RtwqLockPlatform
+@ stdcall MFLockSharedWorkQueue(wstr long ptr ptr) rtworkq.RtwqLockSharedWorkQueue
 @ stdcall MFLockWorkQueue(long) rtworkq.RtwqLockWorkQueue
 @ stdcall MFMapDX9FormatToDXGIFormat(long)
 @ stdcall MFMapDXGIFormatToDX9Format(long)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 18361d4d721..1b24dce2fe0 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -240,6 +240,7 @@ static HRESULT (WINAPI *pMFCreateVideoSampleAllocatorEx)(REFIID riid, void **all
 static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surface, UINT subresource, BOOL bottomup,
         IMFMediaBuffer **buffer);
 static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **media_type);
+static HRESULT (WINAPI *pMFLockSharedWorkQueue)(const WCHAR *name, LONG base_priority, DWORD *taskid, DWORD *queue);
 
 static HWND create_window(void)
 {
@@ -907,6 +908,7 @@ static void init_functions(void)
     X(MFCreateVideoSampleAllocatorEx);
     X(MFGetPlaneSize);
     X(MFGetStrideForBitmapInfoHeader);
+    X(MFLockSharedWorkQueue);
     X(MFMapDX9FormatToDXGIFormat);
     X(MFMapDXGIFormatToDX9Format);
     X(MFPutWaitingWorkItem);
@@ -7016,6 +7018,49 @@ done:
     DestroyWindow(window);
 }
 
+static void test_MFLockSharedWorkQueue(void)
+{
+    DWORD taskid, queue, queue2;
+    HRESULT hr;
+
+    if (!pMFLockSharedWorkQueue)
+    {
+        win_skip("MFLockSharedWorkQueue() is not available.\n");
+        return;
+    }
+
+    hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
+    ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
+
+    hr = pMFLockSharedWorkQueue(NULL, 0, &taskid, &queue);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    hr = pMFLockSharedWorkQueue(NULL, 0, NULL, &queue);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    taskid = 0;
+    hr = pMFLockSharedWorkQueue(L"", 0, &taskid, &queue);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    queue = 0;
+    hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue);
+    ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
+
+    queue2 = 0;
+    hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue2);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(queue == queue2, "Unexpected queue %#x.\n", queue2);
+
+    hr = MFUnlockWorkQueue(queue2);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = MFUnlockWorkQueue(queue);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = MFShutdown();
+    ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
+}
+
 START_TEST(mfplat)
 {
     char **argv;
@@ -7044,6 +7089,7 @@ START_TEST(mfplat)
     test_source_resolver();
     test_MFCreateAsyncResult();
     test_allocate_queue();
+    test_MFLockSharedWorkQueue();
     test_MFCopyImage();
     test_MFCreateCollection();
     test_MFHeapAlloc();
diff --git a/dlls/rtworkq/queue.c b/dlls/rtworkq/queue.c
index f4e9f10d3f0..6817b06f284 100644
--- a/dlls/rtworkq/queue.c
+++ b/dlls/rtworkq/queue.c
@@ -58,6 +58,7 @@ 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 DWORD shared_mt_queue;
 
 static CRITICAL_SECTION queues_section;
 static CRITICAL_SECTION_DEBUG queues_critsect_debug =
@@ -217,6 +218,7 @@ static HRESULT unlock_user_queue(DWORD queue)
     {
         if (--entry->refcount == 0)
         {
+            if (shared_mt_queue == queue) shared_mt_queue = 0;
             shutdown_queue((struct queue *)entry->obj);
             heap_free(entry->obj);
             entry->obj = next_free_user_queue;
@@ -1438,9 +1440,37 @@ HRESULT WINAPI RtwqSetLongRunning(DWORD queue_id, BOOL enable)
 
 HRESULT WINAPI RtwqLockSharedWorkQueue(const WCHAR *usageclass, LONG priority, DWORD *taskid, DWORD *queue)
 {
-    FIXME("%s, %d, %p, %p.\n", debugstr_w(usageclass), priority, taskid, queue);
+    struct queue_desc desc;
+    HRESULT hr;
+
+    TRACE("%s, %d, %p, %p.\n", debugstr_w(usageclass), priority, taskid, queue);
+
+    if (!usageclass)
+        return E_POINTER;
+
+    if (!*usageclass && taskid)
+        return E_INVALIDARG;
+
+    if (*usageclass)
+        FIXME("Class name is ignored.\n");
+
+    EnterCriticalSection(&queues_section);
 
-    return RtwqAllocateWorkQueue(RTWQ_STANDARD_WORKQUEUE, queue);
+    if (shared_mt_queue)
+        hr = lock_user_queue(shared_mt_queue);
+    else
+    {
+        desc.queue_type = RTWQ_MULTITHREADED_WORKQUEUE;
+        desc.ops = &pool_queue_ops;
+        desc.target_queue = 0;
+        hr = alloc_user_queue(&desc, &shared_mt_queue);
+    }
+
+    *queue = shared_mt_queue;
+
+    LeaveCriticalSection(&queues_section);
+
+    return hr;
 }
 
 HRESULT WINAPI RtwqSetDeadline(DWORD queue_id, LONGLONG deadline, HANDLE *request)
diff --git a/include/mfapi.h b/include/mfapi.h
index d6969984da7..c1cf766c005 100644
--- a/include/mfapi.h
+++ b/include/mfapi.h
@@ -553,6 +553,7 @@ HRESULT WINAPI MFInitAttributesFromBlob(IMFAttributes *attributes, const UINT8 *
 HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size);
 HRESULT WINAPI MFInvokeCallback(IMFAsyncResult *result);
 HRESULT WINAPI MFLockPlatform(void);
+HRESULT WINAPI MFLockSharedWorkQueue(const WCHAR *name, LONG base_priority, DWORD *taskid, DWORD *queue);
 DXGI_FORMAT WINAPI MFMapDX9FormatToDXGIFormat(DWORD format);
 DWORD WINAPI MFMapDXGIFormatToDX9Format(DXGI_FORMAT dxgi_format);
 HRESULT WINAPI MFPutWaitingWorkItem(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
-- 
2.30.2




More information about the wine-devel mailing list