Signed-off-by: Derek Lesho dlesho@codeweavers.com --- v2: Use CoInitialize and CoUninitialize instead of TLS. --- dlls/mfplat/tests/mfplat.c | 86 ++++++++++++++++++++++++++++++++++++++ dlls/rtworkq/Makefile.in | 1 + dlls/rtworkq/queue.c | 4 ++ 3 files changed, 91 insertions(+)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index c468286362..f056bbda2a 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -2220,6 +2220,91 @@ static void test_allocate_queue(void) ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); }
+static HRESULT WINAPI test_get_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +{ + struct test_callback *callback = impl_from_IMFAsyncCallback(iface); + APTTYPE com_type; + APTTYPEQUALIFIER qualifier; + HRESULT hr; + + hr = CoGetApartmentType(&com_type, &qualifier); + ok (SUCCEEDED(hr), "Failed to get apartment type, hr %#x.\n", hr); + if (SUCCEEDED(hr)) + { + ok (com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE, + "Unexpected type %u, qualifier %u.\n", com_type, qualifier); + } + + SetEvent(callback->event); + return S_OK; +} + +static const IMFAsyncCallbackVtbl test_get_com_state_callback_vtbl = +{ + testcallback_QueryInterface, + testcallback_AddRef, + testcallback_Release, + testcallback_GetParameters, + test_get_com_state_callback_Invoke, +}; + +static void test_queue_com_state(void) +{ + DWORD standard, multithreaded, window; + struct test_callback callback = { { &test_get_com_state_callback_vtbl } }; + HRESULT hr; + + callback.event = CreateEventA(NULL, TRUE, FALSE, NULL); + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr); + + for (DWORD i = MFASYNC_CALLBACK_QUEUE_STANDARD; i <= MFASYNC_CALLBACK_QUEUE_MULTITHREADED; i++) + { + hr = MFPutWorkItem(i, &callback.IMFAsyncCallback_iface, NULL); + ok (SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr); + WaitForSingleObject(callback.event, INFINITE); + ResetEvent(callback.event); + } + + hr = MFAllocateWorkQueueEx(MF_STANDARD_WORKQUEUE, &standard); + ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr); + + hr = MFAllocateWorkQueueEx(MF_MULTITHREADED_WORKQUEUE, &multithreaded); + ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr); + + hr = MFAllocateWorkQueueEx(MF_WINDOW_WORKQUEUE, &window); + ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr); + + hr = MFPutWorkItem(standard, &callback.IMFAsyncCallback_iface, NULL); + ok (SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr); + WaitForSingleObject(callback.event, INFINITE); + ResetEvent(callback.event); + + hr = MFPutWorkItem(multithreaded, &callback.IMFAsyncCallback_iface, NULL); + ok (SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr); + WaitForSingleObject(callback.event, INFINITE); + ResetEvent(callback.event); + + hr = MFPutWorkItem(window, &callback.IMFAsyncCallback_iface, NULL); + ok (SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr); + WaitForSingleObject(callback.event, INFINITE); + + CloseHandle(callback.event); + + hr = MFUnlockWorkQueue(standard); + ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr); + + hr = MFUnlockWorkQueue(multithreaded); + ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr); + + hr = MFUnlockWorkQueue(window); + ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr); + + hr = MFShutdown(); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); +} + static void test_MFCopyImage(void) { BYTE dest[16], src[16]; @@ -4135,6 +4220,7 @@ START_TEST(mfplat) test_source_resolver(); test_MFCreateAsyncResult(); test_allocate_queue(); + test_queue_com_state(); test_MFCopyImage(); test_MFCreateCollection(); test_MFHeapAlloc(); diff --git a/dlls/rtworkq/Makefile.in b/dlls/rtworkq/Makefile.in index a224198986..b356b3cb24 100644 --- a/dlls/rtworkq/Makefile.in +++ b/dlls/rtworkq/Makefile.in @@ -1,5 +1,6 @@ MODULE = rtworkq.dll IMPORTLIB = rtworkq +IMPORTS = ole32
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/rtworkq/queue.c b/dlls/rtworkq/queue.c index a2fb3824c3..a65167789f 100644 --- a/dlls/rtworkq/queue.c +++ b/dlls/rtworkq/queue.c @@ -333,8 +333,12 @@ static void CALLBACK standard_queue_worker(TP_CALLBACK_INSTANCE *instance, void
TRACE("result object %p.\n", result);
+ CoInitializeEx(NULL, COINIT_MULTITHREADED); + IRtwqAsyncCallback_Invoke(result->pCallback, item->result);
+ CoUninitialize(); + release_work_item(item); }