windows.media.speech/tests: Add tests to check if IAsyncInfo_Close is non blocking.
Signed-off-by: Bernhard Kölbl <besentv@gmail.com> Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5839f1da7f
commit
9d67ca493a
|
@ -239,8 +239,8 @@ struct compilation_handler
|
||||||
IAsyncHandler_Compilation IAsyncHandler_Compilation_iface;
|
IAsyncHandler_Compilation IAsyncHandler_Compilation_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
|
||||||
|
HANDLE event_block;
|
||||||
HANDLE event_finished;
|
HANDLE event_finished;
|
||||||
BOOLEAN sleeping;
|
|
||||||
DWORD thread_id;
|
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("Iface %p, info %p, status %d.\n", iface, info, status);
|
||||||
trace("Caller thread id %lu callback thread id %lu.\n", impl->thread_id, id);
|
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);
|
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;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -813,6 +815,23 @@ static void test_VoiceInformation(void)
|
||||||
RoUninitialize();
|
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 void test_SpeechRecognizer(void)
|
||||||
{
|
{
|
||||||
static const WCHAR *speech_recognition_name = L"Windows.Media.SpeechRecognition.SpeechRecognizer";
|
static const WCHAR *speech_recognition_name = L"Windows.Media.SpeechRecognition.SpeechRecognizer";
|
||||||
|
@ -828,16 +847,17 @@ static void test_SpeechRecognizer(void)
|
||||||
ISpeechRecognizer2 *recognizer2 = NULL;
|
ISpeechRecognizer2 *recognizer2 = NULL;
|
||||||
IActivationFactory *factory = NULL;
|
IActivationFactory *factory = NULL;
|
||||||
IInspectable *inspectable = NULL;
|
IInspectable *inspectable = NULL;
|
||||||
IClosable *closable = NULL;
|
|
||||||
ILanguage *language = NULL;
|
ILanguage *language = NULL;
|
||||||
IAsyncInfo *info = NULL;
|
IAsyncInfo *info = NULL;
|
||||||
struct completed_event_handler completed_handler;
|
struct completed_event_handler completed_handler;
|
||||||
struct recognition_result_handler result_handler;
|
struct recognition_result_handler result_handler;
|
||||||
|
struct async_operation_block_param block_param;
|
||||||
struct compilation_handler compilation_handler;
|
struct compilation_handler compilation_handler;
|
||||||
SpeechRecognitionResultStatus result_status;
|
SpeechRecognitionResultStatus result_status;
|
||||||
EventRegistrationToken token = { .value = 0 };
|
EventRegistrationToken token = { .value = 0 };
|
||||||
AsyncStatus async_status;
|
AsyncStatus async_status;
|
||||||
HSTRING hstr, hstr_lang;
|
HSTRING hstr, hstr_lang;
|
||||||
|
HANDLE blocked_thread;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
UINT32 id;
|
UINT32 id;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
@ -909,11 +929,16 @@ static void test_SpeechRecognizer(void)
|
||||||
hr = IInspectable_QueryInterface(inspectable, &IID_ISpeechRecognizer2, (void **)&recognizer2);
|
hr = IInspectable_QueryInterface(inspectable, &IID_ISpeechRecognizer2, (void **)&recognizer2);
|
||||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
check_interface(inspectable, &IID_IClosable, TRUE);
|
||||||
|
|
||||||
hr = ISpeechRecognizer2_get_ContinuousRecognitionSession(recognizer2, &session);
|
hr = ISpeechRecognizer2_get_ContinuousRecognitionSession(recognizer2, &session);
|
||||||
ok(hr == S_OK, "ISpeechRecognizer2_get_ContinuousRecognitionSession failed, hr %#lx.\n", hr);
|
ok(hr == S_OK, "ISpeechRecognizer2_get_ContinuousRecognitionSession failed, hr %#lx.\n", hr);
|
||||||
check_refcount(session, 2);
|
check_refcount(session, 2);
|
||||||
check_refcount(inspectable, 3);
|
check_refcount(inspectable, 3);
|
||||||
|
|
||||||
|
ref = ISpeechRecognizer2_Release(recognizer2);
|
||||||
|
ok(ref == 2, "Got unexpected ref %lu.\n", ref);
|
||||||
|
|
||||||
hr = ISpeechContinuousRecognitionSession_add_Completed(session, NULL, &token);
|
hr = ISpeechContinuousRecognitionSession_add_Completed(session, NULL, &token);
|
||||||
ok(hr == E_INVALIDARG, "ISpeechContinuousRecognitionSession_add_ResultGenerated failed, hr %#lx.\n", hr);
|
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);
|
hr = ISpeechContinuousRecognitionSession_remove_ResultGenerated(session, token);
|
||||||
ok(hr == S_OK, "ISpeechContinuousRecognitionSession_remove_ResultGenerated failed, hr %#lx.\n", hr);
|
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);
|
hr = ISpeechRecognizer_get_Constraints(recognizer, &constraints);
|
||||||
ok(hr == S_OK, "ISpeechContinuousRecognitionSession_get_Constraints failed, hr %#lx.\n", hr);
|
ok(hr == S_OK, "ISpeechContinuousRecognitionSession_get_Constraints failed, hr %#lx.\n", hr);
|
||||||
|
|
||||||
|
@ -1064,23 +1092,63 @@ static void test_SpeechRecognizer(void)
|
||||||
|
|
||||||
ref = IAsyncInfo_Release(info);
|
ref = IAsyncInfo_Release(info);
|
||||||
todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref);
|
todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref);
|
||||||
|
ref = IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
|
||||||
|
todo_wine ok(!ref, "Got unexpected ref %lu.\n", ref);
|
||||||
|
|
||||||
|
ref = ISpeechRecognizer_Release(recognizer);
|
||||||
|
todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref);
|
||||||
|
|
||||||
|
ref = IInspectable_Release(inspectable);
|
||||||
|
todo_wine ok(!ref, "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);
|
||||||
|
|
||||||
|
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:
|
skip_operation:
|
||||||
ref = IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
|
ref = IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
|
||||||
ok(!ref, "Got unexpected ref %lu.\n", ref);
|
ok(!ref, "Got unexpected ref %lu.\n", ref);
|
||||||
|
|
||||||
ref = ISpeechContinuousRecognitionSession_Release(session);
|
|
||||||
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 = IClosable_Release(closable);
|
|
||||||
ok(ref == 3, "Got unexpected ref %lu.\n", ref);
|
|
||||||
|
|
||||||
ref = ISpeechRecognizer2_Release(recognizer2);
|
|
||||||
ok(ref == 2, "Got unexpected ref %lu.\n", ref);
|
|
||||||
|
|
||||||
ref = ISpeechRecognizer_Release(recognizer);
|
ref = ISpeechRecognizer_Release(recognizer);
|
||||||
ok(ref == 1, "Got unexpected ref %lu.\n", ref);
|
ok(ref == 1, "Got unexpected ref %lu.\n", ref);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue