[PATCH v2 3/6] windows.media.speech/tests: Add tests to check if IAsyncInfo_Close is non blocking.
Bernhard Kölbl
besentv at gmail.com
Fri Apr 22 07:48:04 CDT 2022
Signed-off-by: Bernhard Kölbl <besentv at gmail.com>
---
v2: Remove unnecessary variable name.
---
dlls/windows.media.speech/tests/speech.c | 96 ++++++++++++++++++++----
1 file changed, 82 insertions(+), 14 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c
index 12ac407b751..f1c0f991cec 100644
--- a/dlls/windows.media.speech/tests/speech.c
+++ b/dlls/windows.media.speech/tests/speech.c
@@ -239,8 +239,8 @@ struct compilation_handler
IAsyncHandler_Compilation IAsyncHandler_Compilation_iface;
LONG ref;
+ HANDLE event_block;
HANDLE event_finished;
- BOOLEAN sleeping;
DWORD thread_id;
};
@@ -290,8 +290,10 @@ HRESULT WINAPI compilation_handler_Invoke( IAsyncHandler_Compilation *iface,
trace("Iface %p, info %p, status %d.\n", iface, info, status);
trace("Caller thread id %lu callback thread id %lu.\n", impl->thread_id, id);
- ok(status != Started, "Got unexpected status %#x.\n", status);
+ /* Signal finishing of the handler. */
if (impl->event_finished) SetEvent(impl->event_finished);
+ /* Block handler until event is set. */
+ if (impl->event_block) WaitForSingleObject(impl->event_block, INFINITE);
return S_OK;
}
@@ -813,6 +815,23 @@ static void test_VoiceInformation(void)
RoUninitialize();
}
+struct async_operation_block_param
+{
+ IAsyncOperationCompletedHandler_SpeechRecognitionCompilationResult *handler;
+ IAsyncOperation_SpeechRecognitionCompilationResult *operation;
+};
+
+static DWORD WINAPI async_operation_block_thread(void *arg)
+{
+ struct async_operation_block_param *param = arg;
+ HRESULT hr;
+
+ hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(param->operation, param->handler);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ return 0;
+}
+
static void test_SpeechRecognizer(void)
{
static const WCHAR *speech_recognition_name = L"Windows.Media.SpeechRecognition.SpeechRecognizer";
@@ -828,16 +847,17 @@ static void test_SpeechRecognizer(void)
ISpeechRecognizer2 *recognizer2 = NULL;
IActivationFactory *factory = NULL;
IInspectable *inspectable = NULL;
- IClosable *closable = NULL;
ILanguage *language = NULL;
IAsyncInfo *info = NULL;
struct completed_event_handler completed_handler;
struct recognition_result_handler result_handler;
+ struct async_operation_block_param block_param;
struct compilation_handler compilation_handler;
SpeechRecognitionResultStatus result_status;
EventRegistrationToken token = { .value = 0 };
AsyncStatus async_status;
HSTRING hstr, hstr_lang;
+ HANDLE blocked_thread;
HRESULT hr;
UINT32 id;
LONG ref;
@@ -909,11 +929,16 @@ static void test_SpeechRecognizer(void)
hr = IInspectable_QueryInterface(inspectable, &IID_ISpeechRecognizer2, (void **)&recognizer2);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_interface(inspectable, &IID_IClosable, TRUE);
+
hr = ISpeechRecognizer2_get_ContinuousRecognitionSession(recognizer2, &session);
ok(hr == S_OK, "ISpeechRecognizer2_get_ContinuousRecognitionSession failed, hr %#lx.\n", hr);
check_refcount(session, 2);
check_refcount(inspectable, 3);
+ ref = ISpeechRecognizer2_Release(recognizer2);
+ ok(ref == 2, "Got unexpected ref %lu.\n", ref);
+
hr = ISpeechContinuousRecognitionSession_add_Completed(session, NULL, &token);
ok(hr == E_INVALIDARG, "ISpeechContinuousRecognitionSession_add_ResultGenerated failed, hr %#lx.\n", hr);
@@ -938,6 +963,9 @@ static void test_SpeechRecognizer(void)
hr = ISpeechContinuousRecognitionSession_remove_ResultGenerated(session, token);
ok(hr == S_OK, "ISpeechContinuousRecognitionSession_remove_ResultGenerated failed, hr %#lx.\n", hr);
+ ref = ISpeechContinuousRecognitionSession_Release(session);
+ ok(ref == 1, "Got unexpected ref %lu.\n", ref);
+
hr = ISpeechRecognizer_get_Constraints(recognizer, &constraints);
ok(hr == S_OK, "ISpeechContinuousRecognitionSession_get_Constraints failed, hr %#lx.\n", hr);
@@ -1064,22 +1092,62 @@ static void test_SpeechRecognizer(void)
ref = IAsyncInfo_Release(info);
todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref);
-
-skip_operation:
ref = IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
- ok(!ref, "Got unexpected ref %lu.\n", ref);
+ todo_wine ok(!ref, "Got unexpected ref %lu.\n", ref);
- ref = ISpeechContinuousRecognitionSession_Release(session);
- ok(ref == 1, "Got unexpected ref %lu.\n", ref);
+ ref = ISpeechRecognizer_Release(recognizer);
+ todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref);
- hr = IInspectable_QueryInterface(inspectable, &IID_IClosable, (void **)&closable);
- ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ref = IInspectable_Release(inspectable);
+ todo_wine ok(!ref, "Got unexpected ref %lu.\n", ref);
- ref = IClosable_Release(closable);
- ok(ref == 3, "Got unexpected ref %lu.\n", ref);
+ /* Test if AsyncInfo_Close waits for the handler to finish. */
+ hr = RoActivateInstance(hstr, &inspectable);
+ todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- ref = ISpeechRecognizer2_Release(recognizer2);
- ok(ref == 2, "Got unexpected ref %lu.\n", ref);
+ hr = IInspectable_QueryInterface(inspectable, &IID_ISpeechRecognizer, (void **)&recognizer);
+ todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ compilation_handler_create_static(&compilation_handler);
+ compilation_handler.event_block = CreateEventW(NULL, FALSE, FALSE, NULL);
+ compilation_handler.event_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
+ compilation_handler.thread_id = GetCurrentThreadId();
+
+ todo_wine ok(compilation_handler.event_finished != NULL, "Finished event wasn't created.\n");
+
+ hr = ISpeechRecognizer_CompileConstraintsAsync(recognizer, &operation);
+ todo_wine ok(hr == S_OK, "ISpeechRecognizer_CompileConstraintsAsync failed, hr %#lx.\n", hr);
+
+ block_param.handler = &compilation_handler.IAsyncHandler_Compilation_iface;
+ block_param.operation = operation;
+ blocked_thread = CreateThread(NULL, 0, async_operation_block_thread, &block_param, 0, NULL);
+
+ todo_wine ok(!WaitForSingleObject(compilation_handler.event_finished, 5000), "Wait for event_finished failed.\n");
+
+ todo_wine ok(WaitForSingleObject(blocked_thread, 100) == WAIT_TIMEOUT, "Wait for block_thread didn't time out.\n");
+
+ todo_wine ok(compilation_handler.ref == 3, "Got unexpected ref %lu.\n", compilation_handler.ref);
+ todo_wine check_refcount(operation, 3);
+
+ hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info);
+ todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ hr = IAsyncInfo_Close(info); /* If IAsyncInfo_Close would wait for the handler to finish, the test would get stuck here. */
+ todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ SetEvent(compilation_handler.event_block);
+ todo_wine ok(!WaitForSingleObject(blocked_thread, 1000), "Wait for block_thread failed.\n");
+
+ CloseHandle(blocked_thread);
+ CloseHandle(compilation_handler.event_block);
+ CloseHandle(compilation_handler.event_finished);
+
+ ref = IAsyncInfo_Release(info);
+ todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref);
+
+skip_operation:
+ ref = IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
+ ok(!ref, "Got unexpected ref %lu.\n", ref);
ref = ISpeechRecognizer_Release(recognizer);
ok(ref == 1, "Got unexpected ref %lu.\n", ref);
--
2.35.1
More information about the wine-devel
mailing list