Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/tests/speech.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index ef75178f8c1..e4d65d3afd4 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -858,6 +858,8 @@ static void test_SpeechRecognizer(void) goto done; }
+ check_interface(factory, &IID_IAgileObject, TRUE); + hr = IActivationFactory_QueryInterface(factory, &IID_ISpeechRecognizerFactory, (void **)&sr_factory); ok(hr == S_OK, "IActivationFactory_QueryInterface IID_ISpeechRecognizer failed, hr %#lx.\n", hr);
@@ -901,7 +903,6 @@ static void test_SpeechRecognizer(void) if (hr == S_OK) { check_refcount(inspectable, 1); - check_interface(factory, &IID_IAgileObject, TRUE);
hr = IInspectable_QueryInterface(inspectable, &IID_ISpeechRecognizer, (void **)&recognizer); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); @@ -1068,8 +1069,6 @@ static void test_SpeechRecognizer(void) todo_wine ok(hr == S_OK, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr); todo_wine ok(async_status == Started || async_status == Completed, "Status was %#x.\n", async_status);
- IAsyncInfo_Release(info); - hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler2.IAsyncHandler_Compilation_iface); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
@@ -1081,6 +1080,9 @@ static void test_SpeechRecognizer(void) todo_wine ok(hr == S_OK, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr); todo_wine ok(async_status == Completed, "Status was %#x.\n", async_status);
+ 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);
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/tests/speech.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index e4d65d3afd4..a8064948bd2 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -76,6 +76,14 @@ static inline void check_refcount_(unsigned int line, void *obj, LONG exp) ok_(__FILE__, line)(exp == ref, "Unexpected refcount %lu, expected %lu\n", ref, exp); }
+#define equal_refcount(obj, obj2) equal_refcount_(__LINE__, obj, obj2) +static inline void equal_refcount_(unsigned int line, void *obj, void *obj2) +{ + LONG ref = get_ref(obj); + LONG ref2 = get_ref(obj2); + ok_(__FILE__, line)(ref == ref2, "Unequal refcount. Got obj_ref %lu, obj2_ref %lu\n", ref, ref2); +} + #define check_interface(obj, iid, exp) check_interface_(__LINE__, obj, iid, exp) static void check_interface_(unsigned int line, void *obj, const IID *iid, BOOL supported) { @@ -996,13 +1004,7 @@ static void test_SpeechRecognizer(void) hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- /* Check if AsyncInfo and AsyncOperation share the same refcount. */ - IAsyncOperation_SpeechRecognitionCompilationResult_AddRef(operation); - todo_wine check_refcount(operation, 3); - todo_wine check_refcount(info, 3); - - IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation); - todo_wine check_refcount(info, 2); + todo_wine equal_refcount(operation, info);
id = 0xdeadbeef; hr = IAsyncInfo_get_Id(info, &id);
On 4/20/22 21:34, Bernhard Kölbl wrote:
Signed-off-by: Bernhard Kölbl besentv@gmail.com
dlls/windows.media.speech/tests/speech.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index e4d65d3afd4..a8064948bd2 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -76,6 +76,14 @@ static inline void check_refcount_(unsigned int line, void *obj, LONG exp) ok_(__FILE__, line)(exp == ref, "Unexpected refcount %lu, expected %lu\n", ref, exp); }
+#define equal_refcount(obj, obj2) equal_refcount_(__LINE__, obj, obj2) +static inline void equal_refcount_(unsigned int line, void *obj, void *obj2) +{
- LONG ref = get_ref(obj);
- LONG ref2 = get_ref(obj2);
- ok_(__FILE__, line)(ref == ref2, "Unequal refcount. Got obj_ref %lu, obj2_ref %lu\n", ref, ref2);
+}
- #define check_interface(obj, iid, exp) check_interface_(__LINE__, obj, iid, exp) static void check_interface_(unsigned int line, void *obj, const IID *iid, BOOL supported) {
@@ -996,13 +1004,7 @@ static void test_SpeechRecognizer(void) hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Check if AsyncInfo and AsyncOperation share the same refcount. */
IAsyncOperation_SpeechRecognitionCompilationResult_AddRef(operation);
todo_wine check_refcount(operation, 3);
todo_wine check_refcount(info, 3);
IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
todo_wine check_refcount(info, 2);
todo_wine equal_refcount(operation, info); id = 0xdeadbeef; hr = IAsyncInfo_get_Id(info, &id);
I could probably sign this off to avoid resending, but to be honest I'm not sure it's really useful to check this.
As you queried the IAsyncInfo interface on operation, it's pretty much implicit that both are the same object.
So, I just drop this one?
Am Do., 21. Apr. 2022 um 16:34 Uhr schrieb Rémi Bernon rbernon@codeweavers.com:
On 4/20/22 21:34, Bernhard Kölbl wrote:
Signed-off-by: Bernhard Kölbl besentv@gmail.com
dlls/windows.media.speech/tests/speech.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index e4d65d3afd4..a8064948bd2 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -76,6 +76,14 @@ static inline void check_refcount_(unsigned int line, void *obj, LONG exp) ok_(__FILE__, line)(exp == ref, "Unexpected refcount %lu, expected %lu\n", ref, exp); }
+#define equal_refcount(obj, obj2) equal_refcount_(__LINE__, obj, obj2) +static inline void equal_refcount_(unsigned int line, void *obj, void *obj2) +{
- LONG ref = get_ref(obj);
- LONG ref2 = get_ref(obj2);
- ok_(__FILE__, line)(ref == ref2, "Unequal refcount. Got obj_ref %lu, obj2_ref %lu\n", ref, ref2);
+}
- #define check_interface(obj, iid, exp) check_interface_(__LINE__, obj, iid, exp) static void check_interface_(unsigned int line, void *obj, const IID *iid, BOOL supported) {
@@ -996,13 +1004,7 @@ static void test_SpeechRecognizer(void) hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Check if AsyncInfo and AsyncOperation share the same refcount. */
IAsyncOperation_SpeechRecognitionCompilationResult_AddRef(operation);
todo_wine check_refcount(operation, 3);
todo_wine check_refcount(info, 3);
IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
todo_wine check_refcount(info, 2);
todo_wine equal_refcount(operation, info); id = 0xdeadbeef; hr = IAsyncInfo_get_Id(info, &id);
I could probably sign this off to avoid resending, but to be honest I'm not sure it's really useful to check this.
As you queried the IAsyncInfo interface on operation, it's pretty much implicit that both are the same object.
-- Rémi Bernon rbernon@codeweavers.com
On 4/22/22 11:55, Bernhard Kölbl wrote:
So, I just drop this one?
I think, or better remove the checks with the other tests removal changes, as you prefer.
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/tests/speech.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index a8064948bd2..dc3742ac402 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -976,7 +976,7 @@ static void test_SpeechRecognizer(void) todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); todo_wine check_refcount(&compilation_handler.IAsyncHandler_Compilation_iface, 1);
- WaitForSingleObject(compilation_handler.event_finished, INFINITE); + todo_wine ok(!WaitForSingleObject(compilation_handler.event_finished, 1000), "Wait for event_finished failed.\n"); CloseHandle(compilation_handler.event_finished);
hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, NULL); @@ -1074,7 +1074,7 @@ static void test_SpeechRecognizer(void) hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler2.IAsyncHandler_Compilation_iface); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- WaitForSingleObject(compilation_handler2.event_finished, INFINITE); + todo_wine ok(!WaitForSingleObject(compilation_handler2.event_finished, 1000), "Wait for event_finished failed.\n"); CloseHandle(compilation_handler2.event_finished);
async_status = 0xdeadbeef;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
1000ms seems to be a bit low in PATCH 6, but maybe because you also spawn a new thread? Assuming this is enough here.
On Win10 1507 x32.
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/tests/speech.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index dc3742ac402..dd699da9bcd 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -985,7 +985,8 @@ static void test_SpeechRecognizer(void) handler = (void*)0xdeadbeef; hr = IAsyncOperation_SpeechRecognitionCompilationResult_get_Completed(operation, &handler); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine ok(handler == NULL, "Handler had value %p.\n", handler); + /* Broken on Win10 1507 x32... */ + todo_wine ok(handler == NULL || broken(handler != &compilation_handler.IAsyncHandler_Compilation_iface), "Handler had value %p.\n", handler);
hr = IAsyncOperation_SpeechRecognitionCompilationResult_GetResults(operation, &compilation_result); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
On 4/20/22 21:34, Bernhard Kölbl wrote:
On Win10 1507 x32.
Signed-off-by: Bernhard Kölbl besentv@gmail.com
dlls/windows.media.speech/tests/speech.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index dc3742ac402..dd699da9bcd 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -985,7 +985,8 @@ static void test_SpeechRecognizer(void) handler = (void*)0xdeadbeef; hr = IAsyncOperation_SpeechRecognitionCompilationResult_get_Completed(operation, &handler); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
todo_wine ok(handler == NULL, "Handler had value %p.\n", handler);
/* Broken on Win10 1507 x32... */
todo_wine ok(handler == NULL || broken(handler != &compilation_handler.IAsyncHandler_Compilation_iface), "Handler had value %p.\n", handler); hr = IAsyncOperation_SpeechRecognitionCompilationResult_GetResults(operation, &compilation_result); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
As far as I can tell, the correct condition is:
handler == NULL || handler == &compilation_handler.IAsyncHandler_Compilation_iface
It only seems to happen if the test is compiled on the testbot, like when submitting the patch manually, and it seems to be happening when the test is executed too soon, even though you waited for completion.
Adding a Sleep also makes handler == NULL consistently happen.
I believe that (possibly on this specific windows version) the handler is removed after its has executed, and that sometimes happens after you completed the wait and called get_Completed.
I think you should probably remove the test altogether as it's unreliable.
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/tests/speech.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index dd699da9bcd..908e04bb0c3 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -974,7 +974,6 @@ static void test_SpeechRecognizer(void)
hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler.IAsyncHandler_Compilation_iface); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine check_refcount(&compilation_handler.IAsyncHandler_Compilation_iface, 1);
todo_wine ok(!WaitForSingleObject(compilation_handler.event_finished, 1000), "Wait for event_finished failed.\n"); CloseHandle(compilation_handler.event_finished); @@ -1061,16 +1060,10 @@ static void test_SpeechRecognizer(void) hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- /* This one can fail, if the async operation had already finished */ - compilation_result = (void*)0xdeadbeef; - hr = IAsyncOperation_SpeechRecognitionCompilationResult_GetResults(operation, &compilation_result); - todo_wine ok(hr == E_ILLEGAL_METHOD_CALL, "Got unexpected hr %#lx.\n", hr); - todo_wine ok(compilation_result == (void*)0xdeadbeef, "Compilation result had value %p.\n", compilation_result); - async_status = 0xdeadbeef; hr = IAsyncInfo_get_Status(info, &async_status); todo_wine ok(hr == S_OK, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr); - todo_wine ok(async_status == Started || async_status == Completed, "Status was %#x.\n", async_status); + todo_wine ok(async_status != AsyncStatus_Closed, "Status was %#x.\n", async_status);
hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler2.IAsyncHandler_Compilation_iface); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
On 4/20/22 21:34, Bernhard Kölbl wrote:
Signed-off-by: Bernhard Kölbl besentv@gmail.com
dlls/windows.media.speech/tests/speech.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index dd699da9bcd..908e04bb0c3 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -974,7 +974,6 @@ static void test_SpeechRecognizer(void)
hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler.IAsyncHandler_Compilation_iface); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
todo_wine check_refcount(&compilation_handler.IAsyncHandler_Compilation_iface, 1); todo_wine ok(!WaitForSingleObject(compilation_handler.event_finished, 1000), "Wait for event_finished failed.\n"); CloseHandle(compilation_handler.event_finished);
@@ -1061,16 +1060,10 @@ static void test_SpeechRecognizer(void) hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* This one can fail, if the async operation had already finished */
compilation_result = (void*)0xdeadbeef;
hr = IAsyncOperation_SpeechRecognitionCompilationResult_GetResults(operation, &compilation_result);
todo_wine ok(hr == E_ILLEGAL_METHOD_CALL, "Got unexpected hr %#lx.\n", hr);
todo_wine ok(compilation_result == (void*)0xdeadbeef, "Compilation result had value %p.\n", compilation_result);
async_status = 0xdeadbeef; hr = IAsyncInfo_get_Status(info, &async_status); todo_wine ok(hr == S_OK, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr);
todo_wine ok(async_status == Started || async_status == Completed, "Status was %#x.\n", async_status);
todo_wine ok(async_status != AsyncStatus_Closed, "Status was %#x.\n", async_status); hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler2.IAsyncHandler_Compilation_iface); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
Looks alright, but as you should probably remove the test from PATCH 3, I suggest you squash this with it.
On 4/21/22 16:54, Rémi Bernon wrote:
On 4/20/22 21:34, Bernhard Kölbl wrote:
Signed-off-by: Bernhard Kölbl besentv@gmail.com
dlls/windows.media.speech/tests/speech.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index dd699da9bcd..908e04bb0c3 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -974,7 +974,6 @@ static void test_SpeechRecognizer(void) hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler.IAsyncHandler_Compilation_iface); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine check_refcount(&compilation_handler.IAsyncHandler_Compilation_iface, 1); todo_wine ok(!WaitForSingleObject(compilation_handler.event_finished, 1000), "Wait for event_finished failed.\n"); CloseHandle(compilation_handler.event_finished); @@ -1061,16 +1060,10 @@ static void test_SpeechRecognizer(void) hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - /* This one can fail, if the async operation had already finished */ - compilation_result = (void*)0xdeadbeef; - hr = IAsyncOperation_SpeechRecognitionCompilationResult_GetResults(operation, &compilation_result); - todo_wine ok(hr == E_ILLEGAL_METHOD_CALL, "Got unexpected hr %#lx.\n", hr); - todo_wine ok(compilation_result == (void*)0xdeadbeef, "Compilation result had value %p.\n", compilation_result);
async_status = 0xdeadbeef; hr = IAsyncInfo_get_Status(info, &async_status); todo_wine ok(hr == S_OK, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr); - todo_wine ok(async_status == Started || async_status == Completed, "Status was %#x.\n", async_status); + todo_wine ok(async_status != AsyncStatus_Closed, "Status was %#x.\n", async_status); hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler2.IAsyncHandler_Compilation_iface); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
Looks alright, but as you should probably remove the test from PATCH 3, I suggest you squash this with it.
PATCH 4 sorry.
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/tests/speech.c | 99 ++++++++++++++++++++---- 1 file changed, 83 insertions(+), 16 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 908e04bb0c3..3766572177f 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -247,8 +247,8 @@ struct compilation_handler IAsyncHandler_Compilation IAsyncHandler_Compilation_iface; LONG ref;
+ HANDLE event_block; HANDLE event_finished; - BOOLEAN sleeping; DWORD thread_id; };
@@ -298,8 +298,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; } @@ -821,6 +823,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"; @@ -836,17 +855,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 compilation_handler compilation_handler, compilation_handler2, compilation_handler3; struct completed_event_handler completed_handler; struct recognition_result_handler result_handler; - struct compilation_handler compilation_handler; - struct compilation_handler compilation_handler2; + struct async_operation_block_param block_param; SpeechRecognitionResultStatus result_status; EventRegistrationToken token = { .value = 0 }; AsyncStatus async_status; HSTRING hstr, hstr_lang; + HANDLE blocked_thread; HRESULT hr; UINT32 id; LONG ref; @@ -918,11 +937,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);
@@ -947,6 +971,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);
@@ -1078,22 +1105,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_handler3); + compilation_handler3.event_block = CreateEventW(NULL, FALSE, FALSE, NULL); + compilation_handler3.event_finished = CreateEventW(NULL, FALSE, FALSE, NULL); + compilation_handler3.thread_id = GetCurrentThreadId(); + + todo_wine ok(compilation_handler3.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_handler3.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_handler3.event_finished, 1000), "Wait for event_finished failed.\n"); + + todo_wine ok(WaitForSingleObject(blocked_thread, 1000) == WAIT_TIMEOUT, "Wait for block_thread didn't time out.\n"); + + todo_wine ok(compilation_handler3.ref == 3, "Got unexpected ref %lu.\n", compilation_handler3.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_handler3.event_block); + todo_wine ok(!WaitForSingleObject(blocked_thread, 1000), "Wait for block_thread failed.\n"); + + CloseHandle(blocked_thread); + CloseHandle(compilation_handler3.event_block); + CloseHandle(compilation_handler3.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);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=113009
Your paranoid android.
=== w1064v1507 (64 bit report) ===
windows.media.speech: speech.c:1138: Test failed: Wait for event_finished failed.
On 4/20/22 21:34, Bernhard Kölbl wrote:
Signed-off-by: Bernhard Kölbl besentv@gmail.com
dlls/windows.media.speech/tests/speech.c | 99 ++++++++++++++++++++---- 1 file changed, 83 insertions(+), 16 deletions(-)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 908e04bb0c3..3766572177f 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -247,8 +247,8 @@ struct compilation_handler IAsyncHandler_Compilation IAsyncHandler_Compilation_iface; LONG ref;
- HANDLE event_block; HANDLE event_finished;
- BOOLEAN sleeping; DWORD thread_id; };
@@ -298,8 +298,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; }
@@ -821,6 +823,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";
@@ -836,17 +855,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 compilation_handler compilation_handler, compilation_handler2, compilation_handler3; struct completed_event_handler completed_handler; struct recognition_result_handler result_handler;
- struct compilation_handler compilation_handler;
- struct compilation_handler compilation_handler2;
- struct async_operation_block_param block_param; SpeechRecognitionResultStatus result_status; EventRegistrationToken token = { .value = 0 }; AsyncStatus async_status; HSTRING hstr, hstr_lang;
- HANDLE blocked_thread; HRESULT hr; UINT32 id; LONG ref;
@@ -918,11 +937,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);
@@ -947,6 +971,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);
@@ -1078,22 +1105,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_handler3);
compilation_handler3.event_block = CreateEventW(NULL, FALSE, FALSE, NULL);
compilation_handler3.event_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
compilation_handler3.thread_id = GetCurrentThreadId();
todo_wine ok(compilation_handler3.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_handler3.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_handler3.event_finished, 1000), "Wait for event_finished failed.\n");
According to the results, it seems like this one is not big enough? I think thread creation can be unusually slow, and sometimes it's best to create them upfront, and instead use an event to start a test. It complicates things a bit though, maybe just increasing the timeout to 5s would be enough.
todo_wine ok(WaitForSingleObject(blocked_thread, 1000) == WAIT_TIMEOUT, "Wait for block_thread didn't time out.\n");
If you expect a timeout, I think it's best to use lower values, like 100ms, otherwise it's always going to wait 1s and slow down the entire test (1s is not much but they pile up).
todo_wine ok(compilation_handler3.ref == 3, "Got unexpected ref %lu.\n", compilation_handler3.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_handler3.event_block);
todo_wine ok(!WaitForSingleObject(blocked_thread, 1000), "Wait for block_thread failed.\n");
CloseHandle(blocked_thread);
CloseHandle(compilation_handler3.event_block);
CloseHandle(compilation_handler3.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);
I still don't see why you need another unique compilation_handler variable, but as there's already compilation_handler2 I'm going to ignore it.
Looks good otherwise.