[PATCH v2 0/5] MR729: windows.media.speech: Initial recognition session work.
-- v2: windows.media.speech: Implement a worker thread for the recognition session. windows.media.speech/tests: Test the recognizer state. windows.media.speech: Return IAsyncAction from session_PauseAsync. windows.media.speech: Return IAsyncAction from session_StopAsync. https://gitlab.winehq.org/wine/wine/-/merge_requests/729
From: Bernhard Kölbl <besentv(a)gmail.com> Signed-off-by: Bernhard Kölbl <besentv(a)gmail.com> --- dlls/windows.media.speech/recognizer.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/dlls/windows.media.speech/recognizer.c b/dlls/windows.media.speech/recognizer.c index 6a058df86e5..9efc73ce367 100644 --- a/dlls/windows.media.speech/recognizer.c +++ b/dlls/windows.media.speech/recognizer.c @@ -156,6 +156,8 @@ struct session ISpeechContinuousRecognitionSession ISpeechContinuousRecognitionSession_iface; LONG ref; + IVector_ISpeechRecognitionConstraint *constraints; + struct list completed_handlers; struct list result_handlers; }; @@ -208,6 +210,7 @@ static ULONG WINAPI session_Release( ISpeechContinuousRecognitionSession *iface { typed_event_handlers_clear(&impl->completed_handlers); typed_event_handlers_clear(&impl->result_handlers); + IVector_ISpeechRecognitionConstraint_Release(impl->constraints); free(impl); } @@ -360,7 +363,6 @@ struct recognizer LONG ref; ISpeechContinuousRecognitionSession *session; - IVector_ISpeechRecognitionConstraint *constraints; }; /* @@ -424,7 +426,6 @@ static ULONG WINAPI recognizer_Release( ISpeechRecognizer *iface ) if (!ref) { ISpeechContinuousRecognitionSession_Release(impl->session); - IVector_ISpeechRecognitionConstraint_Release(impl->constraints); free(impl); } @@ -452,8 +453,11 @@ static HRESULT WINAPI recognizer_GetTrustLevel( ISpeechRecognizer *iface, TrustL static HRESULT WINAPI recognizer_get_Constraints( ISpeechRecognizer *iface, IVector_ISpeechRecognitionConstraint **vector ) { struct recognizer *impl = impl_from_ISpeechRecognizer(iface); + struct session *session = impl_from_ISpeechContinuousRecognitionSession(impl->session); + TRACE("iface %p, operation %p.\n", iface, vector); - IVector_ISpeechRecognitionConstraint_AddRef((*vector = impl->constraints)); + + IVector_ISpeechRecognitionConstraint_AddRef((*vector = session->constraints)); return S_OK; } @@ -797,18 +801,22 @@ static HRESULT WINAPI recognizer_factory_Create( ISpeechRecognizerFactory *iface if (language) FIXME("language parameter unused. Stub!\n"); + /* Init ISpeechContinuousRecognitionSession */ session->ISpeechContinuousRecognitionSession_iface.lpVtbl = &session_vtbl; session->ref = 1; + list_init(&session->completed_handlers); list_init(&session->result_handlers); + if (FAILED(hr = vector_inspectable_create(&constraints_iids, (IVector_IInspectable**)&session->constraints))) + goto error; + + /* Init ISpeechRecognizer */ impl->ISpeechRecognizer_iface.lpVtbl = &speech_recognizer_vtbl; impl->IClosable_iface.lpVtbl = &closable_vtbl; impl->ISpeechRecognizer2_iface.lpVtbl = &speech_recognizer2_vtbl; impl->session = &session->ISpeechContinuousRecognitionSession_iface; impl->ref = 1; - if (FAILED(hr = vector_inspectable_create(&constraints_iids, (IVector_IInspectable**)&impl->constraints))) - goto error; TRACE("created SpeechRecognizer %p.\n", impl); @@ -816,6 +824,7 @@ static HRESULT WINAPI recognizer_factory_Create( ISpeechRecognizerFactory *iface return S_OK; error: + if (session->constraints) IVector_ISpeechRecognitionConstraint_Release(session->constraints); free(session); free(impl); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/729
From: Bernhard Kölbl <besentv(a)gmail.com> Signed-off-by: Bernhard Kölbl <besentv(a)gmail.com> --- dlls/windows.media.speech/recognizer.c | 7 ++++++- dlls/windows.media.speech/tests/speech.c | 24 ++++++++++-------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/dlls/windows.media.speech/recognizer.c b/dlls/windows.media.speech/recognizer.c index 9efc73ce367..3f2e09a252f 100644 --- a/dlls/windows.media.speech/recognizer.c +++ b/dlls/windows.media.speech/recognizer.c @@ -266,10 +266,15 @@ static HRESULT WINAPI session_StartWithModeAsync( ISpeechContinuousRecognitionSe return E_NOTIMPL; } +static HRESULT WINAPI stop_callback( IInspectable *invoker ) +{ + return S_OK; +} + static HRESULT WINAPI session_StopAsync( ISpeechContinuousRecognitionSession *iface, IAsyncAction **action ) { FIXME("iface %p, action %p stub!\n", iface, action); - return E_NOTIMPL; + return async_action_create(NULL, stop_callback, action); } static HRESULT WINAPI session_CancelAsync( ISpeechContinuousRecognitionSession *iface, IAsyncAction **action ) diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 464faaf819a..ff35d75c3b5 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -1762,9 +1762,7 @@ static void test_Recognition(void) */ hr = ISpeechContinuousRecognitionSession_StopAsync(session, &action2); - todo_wine ok(hr == S_OK, "ISpeechContinuousRecognitionSession_StopAsync failed, hr %#lx.\n", hr); - - if (FAILED(hr)) goto skip_action; + ok(hr == S_OK, "ISpeechContinuousRecognitionSession_StopAsync failed, hr %#lx.\n", hr); async_void_handler_create_static(&action_handler); action_handler.event_block = CreateEventW(NULL, FALSE, FALSE, NULL); @@ -1776,40 +1774,38 @@ static void test_Recognition(void) put_param.handler = &action_handler.IAsyncActionCompletedHandler_iface; put_param.action = action2; put_thread = CreateThread(NULL, 0, action_put_completed_thread, &put_param, 0, NULL); - todo_wine ok(!WaitForSingleObject(action_handler.event_finished , 5000), "Wait for event_finished failed.\n"); + ok(!WaitForSingleObject(action_handler.event_finished , 5000), "Wait for event_finished failed.\n"); handler = (void *)0xdeadbeef; old_ref = action_handler.ref; hr = IAsyncAction_get_Completed(action2, &handler); - todo_wine ok(hr == S_OK, "IAsyncAction_get_Completed failed, hr %#lx.\n", hr); + ok(hr == S_OK, "IAsyncAction_get_Completed failed, hr %#lx.\n", hr); - todo_wine ok(handler == &action_handler.IAsyncActionCompletedHandler_iface || /* Broken on 1507. */ - broken(handler != NULL && handler != (void *)0xdeadbeef), "Handler was %p.\n", handler); + todo_wine ok(handler == &action_handler.IAsyncActionCompletedHandler_iface, "Handler was %p.\n", handler); ref = action_handler.ref - old_ref; todo_wine ok(ref == 1, "The ref was increased by %lu.\n", ref); - IAsyncActionCompletedHandler_Release(handler); + if (handler) IAsyncActionCompletedHandler_Release(handler); hr = IAsyncAction_QueryInterface(action2, &IID_IAsyncInfo, (void **)&info); - todo_wine ok(hr == S_OK, "IAsyncAction_QueryInterface failed, hr %#lx.\n", hr); + ok(hr == S_OK, "IAsyncAction_QueryInterface failed, 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, "IAsyncInfo_Close failed, hr %#lx.\n", hr); + ok(hr == S_OK, "IAsyncInfo_Close failed, hr %#lx.\n", hr); check_async_info((IInspectable *)action2, 3, AsyncStatus_Closed, S_OK); set = SetEvent(action_handler.event_block); - todo_wine ok(set == TRUE, "Event 'event_block' wasn't set.\n"); - todo_wine ok(!WaitForSingleObject(put_thread , 1000), "Wait for put_thread failed.\n"); + ok(set == TRUE, "Event 'event_block' wasn't set.\n"); + ok(!WaitForSingleObject(put_thread , 1000), "Wait for put_thread failed.\n"); IAsyncInfo_Release(info); CloseHandle(action_handler.event_finished); CloseHandle(action_handler.event_block); CloseHandle(put_thread); - todo_wine ok(action != action2, "actions were the same!\n"); + ok(action != action2, "actions were the same!\n"); IAsyncAction_Release(action2); -skip_action: IAsyncAction_Release(action); hr = ISpeechContinuousRecognitionSession_remove_ResultGenerated(session, token); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/729
From: Bernhard Kölbl <besentv(a)gmail.com> Signed-off-by: Bernhard Kölbl <besentv(a)gmail.com> --- dlls/windows.media.speech/recognizer.c | 7 ++++++- dlls/windows.media.speech/tests/speech.c | 11 ++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/dlls/windows.media.speech/recognizer.c b/dlls/windows.media.speech/recognizer.c index 3f2e09a252f..958006201e5 100644 --- a/dlls/windows.media.speech/recognizer.c +++ b/dlls/windows.media.speech/recognizer.c @@ -283,10 +283,15 @@ static HRESULT WINAPI session_CancelAsync( ISpeechContinuousRecognitionSession * return E_NOTIMPL; } +static HRESULT WINAPI pause_callback( IInspectable *invoker ) +{ + return S_OK; +} + static HRESULT WINAPI session_PauseAsync( ISpeechContinuousRecognitionSession *iface, IAsyncAction **action ) { FIXME("iface %p, action %p stub!\n", iface, action); - return E_NOTIMPL; + return async_action_create(NULL, pause_callback, action); } static HRESULT WINAPI session_Resume( ISpeechContinuousRecognitionSession *iface ) diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index ff35d75c3b5..8fa4c845d93 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -1761,6 +1761,15 @@ static void test_Recognition(void) * TODO: Use a loopback device together with prerecorded audio files to test the recognizer's functionality. */ + hr = ISpeechContinuousRecognitionSession_PauseAsync(session, &action2); + ok(hr == S_OK, "ISpeechContinuousRecognitionSession_PauseAsync failed, hr %#lx.\n", hr); + await_async_void(action2, &action_handler); + check_async_info((IInspectable *)action2, 3, Completed, S_OK); + IAsyncAction_Release(action2); + + hr = ISpeechContinuousRecognitionSession_Resume(session); + todo_wine ok(hr == S_OK, "ISpeechContinuousRecognitionSession_Resume failed, hr %#lx.\n", hr); + hr = ISpeechContinuousRecognitionSession_StopAsync(session, &action2); ok(hr == S_OK, "ISpeechContinuousRecognitionSession_StopAsync failed, hr %#lx.\n", hr); @@ -1792,7 +1801,7 @@ static void test_Recognition(void) hr = IAsyncInfo_Close(info); /* If IAsyncInfo_Close would wait for the handler to finish, the test would get stuck here. */ ok(hr == S_OK, "IAsyncInfo_Close failed, hr %#lx.\n", hr); - check_async_info((IInspectable *)action2, 3, AsyncStatus_Closed, S_OK); + check_async_info((IInspectable *)action2, 4, AsyncStatus_Closed, S_OK); set = SetEvent(action_handler.event_block); ok(set == TRUE, "Event 'event_block' wasn't set.\n"); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/729
From: Bernhard Kölbl <besentv(a)gmail.com> Signed-off-by: Bernhard Kölbl <besentv(a)gmail.com> --- dlls/windows.media.speech/tests/speech.c | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 8fa4c845d93..ca1f464c1be 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -1619,6 +1619,7 @@ static void test_Recognition(void) struct iterator_hstring iterator_hstring; struct iterable_hstring iterable_hstring; EventRegistrationToken token = { .value = 0 }; + SpeechRecognizerState recog_state; HSTRING commands[3], hstr, tag; HANDLE put_thread; LONG ref, old_ref; @@ -1717,6 +1718,11 @@ static void test_Recognition(void) ok(hr == S_OK, "ISpeechContinuousRecognitionSession_add_ResultGenerated failed, hr %#lx.\n", hr); ok(token.value != 0xdeadbeef, "Got unexpexted token: %#I64x.\n", token.value); + recog_state = 0xdeadbeef; + hr = ISpeechRecognizer2_get_State(recognizer2, &recog_state); + todo_wine ok(hr == S_OK, "ISpeechRecognizer2_get_State failed, hr %#lx.\n", hr); + todo_wine ok(recog_state == SpeechRecognizerState_Idle, "recog_state was %u.\n", recog_state); + hr = ISpeechRecognizer_CompileConstraintsAsync(recognizer, &operation); ok(hr == S_OK, "ISpeechRecognizer_CompileConstraintsAsync failed, hr %#lx.\n", hr); await_async_inspectable((IAsyncOperation_IInspectable *)operation, @@ -1757,6 +1763,11 @@ static void test_Recognition(void) IAsyncInfo_Release(info); + recog_state = 0xdeadbeef; + hr = ISpeechRecognizer2_get_State(recognizer2, &recog_state); + todo_wine ok(hr == S_OK, "ISpeechRecognizer2_get_State failed, hr %#lx.\n", hr); + todo_wine ok(recog_state == SpeechRecognizerState_Capturing, "recog_state was %u.\n", recog_state); + /* * TODO: Use a loopback device together with prerecorded audio files to test the recognizer's functionality. */ @@ -1767,9 +1778,20 @@ static void test_Recognition(void) check_async_info((IInspectable *)action2, 3, Completed, S_OK); IAsyncAction_Release(action2); + recog_state = 0xdeadbeef; + hr = ISpeechRecognizer2_get_State(recognizer2, &recog_state); + todo_wine ok(hr == S_OK, "ISpeechRecognizer2_get_State failed, hr %#lx.\n", hr); + todo_wine ok(recog_state == SpeechRecognizerState_Paused || /* Broken on Win10 1507 */ + broken(recog_state == SpeechRecognizerState_Capturing) , "recog_state was %u.\n", recog_state); + hr = ISpeechContinuousRecognitionSession_Resume(session); todo_wine ok(hr == S_OK, "ISpeechContinuousRecognitionSession_Resume failed, hr %#lx.\n", hr); + recog_state = 0xdeadbeef; + hr = ISpeechRecognizer2_get_State(recognizer2, &recog_state); + todo_wine ok(hr == S_OK, "ISpeechRecognizer2_get_State failed, hr %#lx.\n", hr); + todo_wine ok(recog_state == SpeechRecognizerState_Capturing, "recog_state was %u.\n", recog_state); + hr = ISpeechContinuousRecognitionSession_StopAsync(session, &action2); ok(hr == S_OK, "ISpeechContinuousRecognitionSession_StopAsync failed, hr %#lx.\n", hr); @@ -1817,6 +1839,11 @@ static void test_Recognition(void) IAsyncAction_Release(action2); IAsyncAction_Release(action); + recog_state = 0xdeadbeef; + hr = ISpeechRecognizer2_get_State(recognizer2, &recog_state); + todo_wine ok(hr == S_OK, "ISpeechRecognizer2_get_State failed, hr %#lx.\n", hr); + todo_wine ok(recog_state == SpeechRecognizerState_Idle, "recog_state was %u.\n", recog_state); + hr = ISpeechContinuousRecognitionSession_remove_ResultGenerated(session, token); ok(hr == S_OK, "ISpeechContinuousRecognitionSession_remove_ResultGenerated failed, hr %#lx.\n", hr); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/729
From: Bernhard Kölbl <besentv(a)gmail.com> Signed-off-by: Bernhard Kölbl <besentv(a)gmail.com> --- dlls/windows.media.speech/recognizer.c | 148 ++++++++++++++++++++++- dlls/windows.media.speech/tests/speech.c | 7 +- 2 files changed, 149 insertions(+), 6 deletions(-) diff --git a/dlls/windows.media.speech/recognizer.c b/dlls/windows.media.speech/recognizer.c index 958006201e5..73ce4958f90 100644 --- a/dlls/windows.media.speech/recognizer.c +++ b/dlls/windows.media.speech/recognizer.c @@ -160,6 +160,11 @@ struct session struct list completed_handlers; struct list result_handlers; + + HANDLE session_thread; + HANDLE session_paused_event, session_resume_event; + BOOLEAN session_running, session_paused; + CRITICAL_SECTION cs; }; /* @@ -173,6 +178,51 @@ static inline struct session *impl_from_ISpeechContinuousRecognitionSession( ISp return CONTAINING_RECORD(iface, struct session, ISpeechContinuousRecognitionSession_iface); } +static DWORD CALLBACK session_thread_cb( void *args ) +{ + ISpeechContinuousRecognitionSession *iface = args; + struct session *impl = impl_from_ISpeechContinuousRecognitionSession(iface); + BOOLEAN running, paused = FALSE; + + EnterCriticalSection(&impl->cs); + running = impl->session_running; + LeaveCriticalSection(&impl->cs); + + while (running) + { + EnterCriticalSection(&impl->cs); + paused = impl->session_paused; + running = impl->session_running; + LeaveCriticalSection(&impl->cs); + + /* TODO: Send mic data to recognizer. */ + + if (paused) + { + TRACE("paused!\n"); + SetEvent(impl->session_paused_event); + WaitForSingleObject(impl->session_resume_event, INFINITE); + } + + Sleep(500); /* Sleep to slow down spinning for now. */ + } + + return 0; +} + +static HRESULT WINAPI shutdown_session_thread( ISpeechContinuousRecognitionSession *iface ) +{ + struct session *impl = impl_from_ISpeechContinuousRecognitionSession(iface); + + SetEvent(impl->session_resume_event); /* Set the resume even just in case the session was paused. */ + if (WaitForSingleObject(impl->session_thread, 1000)) + ERR("Wait for shutting down the ISpeechContinuousRecognitionSession timed out!\n"); + CloseHandle(impl->session_thread); + impl->session_thread = NULL; + + return S_OK; +} + static HRESULT WINAPI session_QueryInterface( ISpeechContinuousRecognitionSession *iface, REFIID iid, void **out ) { struct session *impl = impl_from_ISpeechContinuousRecognitionSession(iface); @@ -208,8 +258,21 @@ static ULONG WINAPI session_Release( ISpeechContinuousRecognitionSession *iface if (!ref) { + BOOLEAN running = FALSE; + + EnterCriticalSection(&impl->cs); + running = impl->session_running; + LeaveCriticalSection(&impl->cs); + + if (running) shutdown_session_thread(iface); + typed_event_handlers_clear(&impl->completed_handlers); typed_event_handlers_clear(&impl->result_handlers); + CloseHandle(impl->session_paused_event); + CloseHandle(impl->session_resume_event); + impl->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&impl->cs); + IVector_ISpeechRecognitionConstraint_Release(impl->constraints); free(impl); } @@ -249,13 +312,31 @@ static HRESULT WINAPI session_set_AutoStopSilenceTimeout( ISpeechContinuousRecog static HRESULT WINAPI start_callback( IInspectable *invoker ) { - return S_OK; + struct session *impl = impl_from_ISpeechContinuousRecognitionSession((ISpeechContinuousRecognitionSession *)invoker); + HRESULT hr = S_OK; + + impl->session_running = TRUE; + impl->session_thread = CreateThread(NULL, 0, session_thread_cb, impl, 0, NULL); + + return hr; } static HRESULT WINAPI session_StartAsync( ISpeechContinuousRecognitionSession *iface, IAsyncAction **action ) { + struct session *impl = impl_from_ISpeechContinuousRecognitionSession(iface); + HRESULT hr = S_OK; + FIXME("iface %p, action %p stub!\n", iface, action); - return async_action_create(NULL, start_callback, action); + + EnterCriticalSection(&impl->cs); + if (!impl->session_thread && !impl->session_running && !impl->session_paused) + { + hr = async_action_create((IInspectable *)iface, start_callback, action); + } + else hr = 0x80131509; + LeaveCriticalSection(&impl->cs); + + return hr; } static HRESULT WINAPI session_StartWithModeAsync( ISpeechContinuousRecognitionSession *iface, @@ -268,13 +349,28 @@ static HRESULT WINAPI session_StartWithModeAsync( ISpeechContinuousRecognitionSe static HRESULT WINAPI stop_callback( IInspectable *invoker ) { + shutdown_session_thread((ISpeechContinuousRecognitionSession *)invoker); return S_OK; } static HRESULT WINAPI session_StopAsync( ISpeechContinuousRecognitionSession *iface, IAsyncAction **action ) { + struct session *impl = impl_from_ISpeechContinuousRecognitionSession(iface); + HRESULT hr = 0x80131509; + FIXME("iface %p, action %p stub!\n", iface, action); - return async_action_create(NULL, stop_callback, action); + + EnterCriticalSection(&impl->cs); + if (impl->session_thread && impl->session_running && !impl->session_paused) + { + impl->session_running = FALSE; + LeaveCriticalSection(&impl->cs); + + hr = async_action_create((IInspectable *)iface, stop_callback, action); + } + else LeaveCriticalSection(&impl->cs); + + return hr; } static HRESULT WINAPI session_CancelAsync( ISpeechContinuousRecognitionSession *iface, IAsyncAction **action ) @@ -285,19 +381,51 @@ static HRESULT WINAPI session_CancelAsync( ISpeechContinuousRecognitionSession * static HRESULT WINAPI pause_callback( IInspectable *invoker ) { + struct session *impl = impl_from_ISpeechContinuousRecognitionSession((ISpeechContinuousRecognitionSession *)invoker); + + WaitForSingleObject(impl->session_paused_event, INFINITE); return S_OK; } static HRESULT WINAPI session_PauseAsync( ISpeechContinuousRecognitionSession *iface, IAsyncAction **action ) { + struct session *impl = impl_from_ISpeechContinuousRecognitionSession(iface); + HRESULT hr = 0x80131509; + FIXME("iface %p, action %p stub!\n", iface, action); - return async_action_create(NULL, pause_callback, action); + + EnterCriticalSection(&impl->cs); + if (impl->session_thread && impl->session_running && !impl->session_paused) + { + impl->session_paused = TRUE; + LeaveCriticalSection(&impl->cs); + + hr = async_action_create((IInspectable *)iface, pause_callback, action); + } + else LeaveCriticalSection(&impl->cs); + + return hr; } static HRESULT WINAPI session_Resume( ISpeechContinuousRecognitionSession *iface ) { + struct session *impl = impl_from_ISpeechContinuousRecognitionSession(iface); + HRESULT hr = 0x80131509; + FIXME("iface %p stub!\n", iface); - return E_NOTIMPL; + + EnterCriticalSection(&impl->cs); + if (impl->session_thread && impl->session_running && impl->session_paused) + { + impl->session_paused = FALSE; + LeaveCriticalSection(&impl->cs); + + SetEvent(impl->session_resume_event); + hr = S_OK; + } + else LeaveCriticalSection(&impl->cs); + + return hr; } static HRESULT WINAPI session_add_Completed( ISpeechContinuousRecognitionSession *iface, @@ -814,10 +942,17 @@ static HRESULT WINAPI recognizer_factory_Create( ISpeechRecognizerFactory *iface /* Init ISpeechContinuousRecognitionSession */ session->ISpeechContinuousRecognitionSession_iface.lpVtbl = &session_vtbl; session->ref = 1; + session->session_paused_event = CreateEventW(NULL, FALSE, FALSE, NULL); + session->session_resume_event = CreateEventW(NULL, FALSE, FALSE, NULL); + if (FAILED(hr = HRESULT_FROM_WIN32(GetLastError())) || !session->session_paused_event || !session->session_resume_event) + goto error; list_init(&session->completed_handlers); list_init(&session->result_handlers); + InitializeCriticalSection(&session->cs); + session->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": recognition_session.cs"); + if (FAILED(hr = vector_inspectable_create(&constraints_iids, (IVector_IInspectable**)&session->constraints))) goto error; @@ -835,6 +970,9 @@ static HRESULT WINAPI recognizer_factory_Create( ISpeechRecognizerFactory *iface error: if (session->constraints) IVector_ISpeechRecognitionConstraint_Release(session->constraints); + CloseHandle(session->session_resume_event); + CloseHandle(session->session_paused_event); + DeleteCriticalSection(&session->cs); free(session); free(impl); diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index ca1f464c1be..bb325272599 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -1741,6 +1741,11 @@ static void test_Recognition(void) await_async_void(action, &action_handler); + action2 = (void *)0xdeadbeef; + hr = ISpeechContinuousRecognitionSession_StartAsync(session, &action2); + ok(hr == 0x80131509, "ISpeechContinuousRecognitionSession_StartAsync failed, hr %#lx.\n", hr); + ok(action2 == (void *)0xdeadbeef, "action2 was %p.\n", action2); + hr = IAsyncAction_QueryInterface(action, &IID_IAsyncInfo, (void **)&info); ok(hr == S_OK, "IAsyncAction_QueryInterface failed, hr %#lx.\n", hr); check_async_info((IInspectable *)action, 1, Completed, S_OK); @@ -1785,7 +1790,7 @@ static void test_Recognition(void) broken(recog_state == SpeechRecognizerState_Capturing) , "recog_state was %u.\n", recog_state); hr = ISpeechContinuousRecognitionSession_Resume(session); - todo_wine ok(hr == S_OK, "ISpeechContinuousRecognitionSession_Resume failed, hr %#lx.\n", hr); + ok(hr == S_OK, "ISpeechContinuousRecognitionSession_Resume failed, hr %#lx.\n", hr); recog_state = 0xdeadbeef; hr = ISpeechRecognizer2_get_State(recognizer2, &recog_state); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/729
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=122349 Your paranoid android. === w1064v1507 (64 bit report) === windows.media.speech: speech.c:1747: Test failed: action2 was 0000000000000000. === w1064_adm (64 bit report) === windows.media.speech: speech.c:1747: Test failed: action2 was 0000000000000000.
participants (2)
-
Bernhard Kölbl -
Marvin