Some being more cosmetic than others.
-- v2: windows.media.speech: Assume that async_run_work cannot be NULL in IAsyncInfo_Close. windows.media.speech: Simplify error handling in async_operation_create. windows.media.speech: Initialize HRESULT variables consistently. windows.media.speech: Return E_ILLEGAL_METHOD_CALL from get_ErrorCode.
From: Rémi Bernon rbernon@codeweavers.com
And E_ILLEGAL_METHOD_CALL if called when status isn't Completed or Error.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.media.speech/async.c | 10 +++++----- dlls/windows.media.speech/tests/speech.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/windows.media.speech/async.c b/dlls/windows.media.speech/async.c index 1e6dd336c84..3d3db840fa0 100644 --- a/dlls/windows.media.speech/async.c +++ b/dlls/windows.media.speech/async.c @@ -201,16 +201,16 @@ static HRESULT WINAPI async_operation_GetResults( IAsyncOperation_IInspectable * TRACE("iface %p, results %p.\n", iface, results);
EnterCriticalSection(&impl->cs); - if (impl->status == Closed) + if (impl->status != Completed && impl->status != Error) hr = E_ILLEGAL_METHOD_CALL; - else if (impl->status > Started && impl->result) + else if (!impl->result) + hr = E_UNEXPECTED; + else { *results = impl->result; impl->result = NULL; /* NOTE: AsyncOperation gives up it's reference to result here! */ - hr = S_OK; + hr = impl->hr; } - else - hr = E_UNEXPECTED; LeaveCriticalSection(&impl->cs);
return hr; diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 051b38ce0f9..e6120afdad0 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -988,7 +988,7 @@ static void test_SpeechRecognizer(void)
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); + ok(hr == E_ILLEGAL_METHOD_CALL, "Got unexpected hr %#lx.\n", hr); ok(compilation_result == (void*)0xdeadbeef, "Compilation result had value %p.\n", compilation_result);
hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler.IAsyncHandler_Compilation_iface);
From: Rémi Bernon rbernon@codeweavers.com
When async operation status is Closed.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.media.speech/async.c | 9 +++++++-- dlls/windows.media.speech/tests/speech.c | 12 +++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/dlls/windows.media.speech/async.c b/dlls/windows.media.speech/async.c index 3d3db840fa0..bc5d4fa40ed 100644 --- a/dlls/windows.media.speech/async.c +++ b/dlls/windows.media.speech/async.c @@ -268,13 +268,18 @@ static HRESULT WINAPI async_operation_info_get_Status( IAsyncInfo *iface, AsyncS static HRESULT WINAPI async_operation_info_get_ErrorCode( IAsyncInfo *iface, HRESULT *error_code ) { struct async_operation *impl = impl_from_IAsyncInfo(iface); + HRESULT hr = S_OK; + TRACE("iface %p, error_code %p.\n", iface, error_code);
EnterCriticalSection(&impl->cs); - *error_code = impl->hr; + if (impl->status == Closed) + *error_code = hr = E_ILLEGAL_METHOD_CALL; + else + *error_code = impl->hr; LeaveCriticalSection(&impl->cs);
- return S_OK; + return hr; }
static HRESULT WINAPI async_operation_info_Cancel( IAsyncInfo *iface ) diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index e6120afdad0..9ef49b160cd 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -858,7 +858,7 @@ static void test_SpeechRecognizer(void) AsyncStatus async_status; HSTRING hstr, hstr_lang; HANDLE blocked_thread; - HRESULT hr; + HRESULT hr, error_code; UINT32 id; LONG ref;
@@ -1032,6 +1032,11 @@ static void test_SpeechRecognizer(void) ok(hr == S_OK, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr); ok(async_status == Completed, "Status was %#x.\n", async_status);
+ error_code = 0xdeadbeef; + hr = IAsyncInfo_get_ErrorCode(info, &error_code); + ok(hr == S_OK, "IAsyncInfo_get_ErrorCode failed, hr %#lx.\n", hr); + ok(error_code == S_OK, "ErrorCode was %#lx.\n", error_code); + hr = IAsyncInfo_Cancel(info); ok(hr == S_OK, "IAsyncInfo_Cancel failed, hr %#lx.\n", hr);
@@ -1050,6 +1055,11 @@ static void test_SpeechRecognizer(void) ok(hr == E_ILLEGAL_METHOD_CALL, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr); ok(async_status == AsyncStatus_Closed, "Status was %#x.\n", async_status);
+ error_code = 0xdeadbeef; + hr = IAsyncInfo_get_ErrorCode(info, &error_code); + ok(hr == E_ILLEGAL_METHOD_CALL, "IAsyncInfo_get_ErrorCode failed, hr %#lx.\n", hr); + ok(error_code == E_ILLEGAL_METHOD_CALL, "ErrorCode was %#lx.\n", error_code); + ref = IAsyncInfo_Release(info); ok(ref == 1, "Got unexpected ref %lu.\n", ref);
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.media.speech/async.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/dlls/windows.media.speech/async.c b/dlls/windows.media.speech/async.c index bc5d4fa40ed..3b532502ea2 100644 --- a/dlls/windows.media.speech/async.c +++ b/dlls/windows.media.speech/async.c @@ -176,16 +176,13 @@ static HRESULT WINAPI async_operation_get_Completed( IAsyncOperation_IInspectabl IAsyncOperationCompletedHandler_IInspectable **handler ) { struct async_operation *impl = impl_from_IAsyncOperation_IInspectable(iface); - HRESULT hr; + HRESULT hr = S_OK;
FIXME("iface %p, handler %p semi stub!\n", iface, handler);
EnterCriticalSection(&impl->cs); if (impl->status == Closed) hr = E_ILLEGAL_METHOD_CALL; - else - hr = S_OK; - *handler = (impl->handler != HANDLER_NOT_SET) ? impl->handler : NULL; LeaveCriticalSection(&impl->cs);
@@ -249,16 +246,13 @@ static HRESULT WINAPI async_operation_info_get_Id( IAsyncInfo *iface, UINT32 *id static HRESULT WINAPI async_operation_info_get_Status( IAsyncInfo *iface, AsyncStatus *status ) { struct async_operation *impl = impl_from_IAsyncInfo(iface); - HRESULT hr; + HRESULT hr = S_OK;
TRACE("iface %p, status %p.\n", iface, status);
EnterCriticalSection(&impl->cs); if (impl->status == Closed) hr = E_ILLEGAL_METHOD_CALL; - else - hr = S_OK; - *status = impl->status; LeaveCriticalSection(&impl->cs);
@@ -285,10 +279,9 @@ static HRESULT WINAPI async_operation_info_get_ErrorCode( IAsyncInfo *iface, HRE static HRESULT WINAPI async_operation_info_Cancel( IAsyncInfo *iface ) { struct async_operation *impl = impl_from_IAsyncInfo(iface); - HRESULT hr; + HRESULT hr = S_OK;
TRACE("iface %p.\n", iface); - hr = S_OK;
EnterCriticalSection(&impl->cs); if (impl->status == Closed)
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.media.speech/async.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/dlls/windows.media.speech/async.c b/dlls/windows.media.speech/async.c index 3b532502ea2..418e903476e 100644 --- a/dlls/windows.media.speech/async.c +++ b/dlls/windows.media.speech/async.c @@ -370,16 +370,9 @@ static void CALLBACK async_run_cb(TP_CALLBACK_INSTANCE *instance, void *data, TP HRESULT async_operation_create( const GUID *iid, IInspectable *invoker, async_operation_callback callback, IAsyncOperation_IInspectable **out ) { struct async_operation *impl; - HRESULT hr;
*out = NULL; - - if (!(impl = calloc(1, sizeof(*impl)))) - { - hr = E_OUTOFMEMORY; - goto error; - } - + if (!(impl = calloc(1, sizeof(*impl)))) return E_OUTOFMEMORY; impl->IAsyncOperation_IInspectable_iface.lpVtbl = &async_operation_vtbl; impl->IAsyncInfo_iface.lpVtbl = &async_operation_info_vtbl; impl->iid = iid; @@ -389,11 +382,10 @@ HRESULT async_operation_create( const GUID *iid, IInspectable *invoker, async_op impl->callback = callback; impl->status = Started;
- IAsyncOperation_IInspectable_AddRef(&impl->IAsyncOperation_IInspectable_iface); /* AddRef to keep the obj alive in the callback. */ if (!(impl->async_run_work = CreateThreadpoolWork(async_run_cb, &impl->IAsyncOperation_IInspectable_iface, NULL))) { - hr = HRESULT_FROM_WIN32(GetLastError()); - goto error; + free(impl); + return HRESULT_FROM_WIN32(GetLastError()); }
if (invoker) IInspectable_AddRef((impl->invoker = invoker)); @@ -401,13 +393,11 @@ HRESULT async_operation_create( const GUID *iid, IInspectable *invoker, async_op InitializeCriticalSection(&impl->cs); impl->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": async_operation.cs");
+ /* AddRef to keep the obj alive in the callback. */ + IAsyncOperation_IInspectable_AddRef(&impl->IAsyncOperation_IInspectable_iface); SubmitThreadpoolWork(impl->async_run_work);
*out = &impl->IAsyncOperation_IInspectable_iface; TRACE("created %p\n", *out); return S_OK; - -error: - free(impl); - return hr; }
From: Rémi Bernon rbernon@codeweavers.com
Unless it's closed already.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.media.speech/async.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/dlls/windows.media.speech/async.c b/dlls/windows.media.speech/async.c index 418e903476e..64a095a0134 100644 --- a/dlls/windows.media.speech/async.c +++ b/dlls/windows.media.speech/async.c @@ -296,26 +296,22 @@ static HRESULT WINAPI async_operation_info_Cancel( IAsyncInfo *iface ) static HRESULT WINAPI async_operation_info_Close( IAsyncInfo *iface ) { struct async_operation *impl = impl_from_IAsyncInfo(iface); + HRESULT hr = S_OK;
TRACE("iface %p.\n", iface);
EnterCriticalSection(&impl->cs); if (impl->status == Started) - { - LeaveCriticalSection(&impl->cs); - return E_ILLEGAL_STATE_CHANGE; - } - - if (impl->async_run_work) + hr = E_ILLEGAL_STATE_CHANGE; + else if (impl->status != Closed) { CloseThreadpoolWork(impl->async_run_work); impl->async_run_work = NULL; + impl->status = Closed; } - - impl->status = Closed; LeaveCriticalSection(&impl->cs);
- return S_OK; + return hr; }
static const struct IAsyncInfoVtbl async_operation_info_vtbl =
Added a couple of tests for this.
Bernhard Kölbl (@besentv) commented about dlls/windows.media.speech/tests/speech.c:
ok(hr == E_ILLEGAL_METHOD_CALL, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr); ok(async_status == AsyncStatus_Closed, "Status was %#x.\n", async_status);
error_code = 0xdeadbeef;
hr = IAsyncInfo_get_ErrorCode(info, &error_code);
ok(hr == E_ILLEGAL_METHOD_CALL, "IAsyncInfo_get_ErrorCode failed, hr %#lx.\n", hr);
ok(error_code == E_ILLEGAL_METHOD_CALL, "ErrorCode was %#lx.\n", error_code);
Great. (Dummy comment for Jeremy)