[PATCH 0/3] MR10275: windows.media.speech: Some smaller changes
From: Bernhard Kölbl <bkoelbl@codeweavers.com> --- dlls/windows.media.speech/tests/speech.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 0146f635b2a..63410d6a50c 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -1492,7 +1492,7 @@ static void test_SpeechRecognizer(void) compilation_result = (void *)0xdeadbeef; hr = IAsyncOperation_SpeechRecognitionCompilationResult_GetResults(operation, &compilation_result); todo_wine ok(hr == E_UNEXPECTED, "Got unexpected hr %#lx.\n", hr); - todo_wine ok(compilation_result == NULL, "Got %p.\n", compilation_result); + todo_wine ok(compilation_result == (void *)0xdeadbeef, "Got %p.\n", compilation_result); if (compilation_result && compilation_result != (void *)0xdeadbeef) ISpeechRecognitionCompilationResult_Release(compilation_result); hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10275
From: Bernhard Kölbl <bkoelbl@codeweavers.com> --- dlls/windows.media.speech/tests/speech.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 63410d6a50c..fbd2873330c 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -861,7 +861,7 @@ static void test_SpeechSynthesizer(void) IClosable *closable; struct async_inspectable_handler async_inspectable_handler; HMODULE hdll; - HSTRING str, str2, default_voice_id; + HSTRING str, str2, default_voice_id = NULL; UINT64 value; HRESULT hr; UINT32 size, idx; @@ -936,7 +936,10 @@ static void test_SpeechSynthesizer(void) IAgileObject_Release(tmp_agile_object); hr = IInstalledVoicesStatic_get_AllVoices(voices_static, &voices); - ok(hr == S_OK, "IInstalledVoicesStatic_get_AllVoices failed, hr %#lx\n", hr); + ok(hr == S_OK || broken(hr == COR_E_FILENOTFOUND) /* Broken on Win 8 + 8.1 */, "IInstalledVoicesStatic_get_AllVoices failed, hr %#lx\n", hr); + + if (FAILED(hr)) + goto skip_voices; hr = IVectorView_VoiceInformation_QueryInterface(voices, &IID_IInspectable, (void **)&tmp_inspectable); ok(hr == S_OK, "IVectorView_VoiceInformation_QueryInterface voices failed, hr %#lx\n", hr); @@ -1012,6 +1015,7 @@ static void test_SpeechSynthesizer(void) ref = IVectorView_VoiceInformation_Release(voices); ok(!ref, "Got unexpected ref %lu.\n", ref); +skip_voices: IInstalledVoicesStatic_Release(voices_static); IAgileObject_Release(agile_object); IInspectable_Release(inspectable); @@ -1033,8 +1037,11 @@ static void test_SpeechSynthesizer(void) hr = IVoiceInformation_get_Id(voice, &str); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - hr = WindowsCompareStringOrdinal(str, default_voice_id, &cmp); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (default_voice_id) + { + hr = WindowsCompareStringOrdinal(str, default_voice_id, &cmp); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + } hr = WindowsDeleteString(str); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10275
From: Bernhard Kölbl <bkoelbl@codeweavers.com> --- dlls/windows.media.speech/main.c | 19 +++++++ dlls/windows.media.speech/private.h | 3 + dlls/windows.media.speech/synthesizer.c | 74 +++++++++++++------------ 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/dlls/windows.media.speech/main.c b/dlls/windows.media.speech/main.c index e772a791588..6e0421a0ae3 100644 --- a/dlls/windows.media.speech/main.c +++ b/dlls/windows.media.speech/main.c @@ -24,6 +24,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(speech); +BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) +{ + HRESULT hr; + + switch (reason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(instance); + if (FAILED(hr = static_installed_voices_init())) + WARN("failed to initialize synthesizer voices, hr %#lx.\n", hr); + break; + case DLL_PROCESS_DETACH: + static_installed_voices_deinit(); + break; + } + + return TRUE; +} + HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out) { FIXME("clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out); diff --git a/dlls/windows.media.speech/private.h b/dlls/windows.media.speech/private.h index e7921370f11..e5933da1811 100644 --- a/dlls/windows.media.speech/private.h +++ b/dlls/windows.media.speech/private.h @@ -86,6 +86,9 @@ HRESULT vector_hstring_create( IVector_HSTRING **out ); HRESULT vector_hstring_create_copy( IIterable_HSTRING *iterable, IVector_HSTRING **out ); HRESULT vector_inspectable_create( const struct vector_iids *iids, IVector_IInspectable **out ); +HRESULT static_installed_voices_init(void); +void static_installed_voices_deinit(void); + #define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ static inline impl_type *impl_from( iface_type *iface ) \ { \ diff --git a/dlls/windows.media.speech/synthesizer.c b/dlls/windows.media.speech/synthesizer.c index bbe6181c1d4..c68321a50bb 100644 --- a/dlls/windows.media.speech/synthesizer.c +++ b/dlls/windows.media.speech/synthesizer.c @@ -295,20 +295,7 @@ static ULONG WINAPI vector_view_voice_information_Release( IVectorView_VoiceInfo { struct voice_information_vector *impl = impl_from_IVectorView_VoiceInformation(iface); ULONG ref = InterlockedDecrement(&impl->ref); - UINT32 i; - TRACE("iface %p, ref %lu.\n", iface, ref); - - if (!ref) - { - for (i = 0; i < impl->provider.num_voices; ++i) - { - IVoiceInformation_Release(impl->provider.voices[i]); - impl->provider.voices[i] = 0; - } - impl->provider.num_voices = 0; - } - return ref; } @@ -1693,7 +1680,6 @@ static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInsp if (FAILED(hr = synthesizer_options_create(&impl->options))) goto failed; - /* make sure the provider is initialized */ if (FAILED(hr = IInstalledVoicesStatic_get_AllVoices(&statics->IInstalledVoicesStatic_iface, &voice_infos))) goto failed; @@ -1737,11 +1723,30 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, }; -static HRESULT static_installed_voices_init(void) +/* + * + * IInstalledVoicesStatic for SpeechSynthesizer runtimeclass + * + */ + +DEFINE_IINSPECTABLE(installed_voices_static, IInstalledVoicesStatic, struct synthesizer_statics, IActivationFactory_iface) + +static CRITICAL_SECTION allvoices_cs; +static CRITICAL_SECTION_DEBUG allvoices_critsect_debug = +{ + 0, 0, &allvoices_cs, + { &allvoices_critsect_debug.ProcessLocksList, &allvoices_critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": allvoices_cs") } +}; +static CRITICAL_SECTION allvoices_cs = { &allvoices_critsect_debug, -1, 0, 0, 0, 0 }; + +HRESULT static_installed_voices_init(void) { WCHAR locale[LOCALE_NAME_MAX_LENGTH]; HRESULT hr; + EnterCriticalSection(&allvoices_cs); + if (all_voices.provider.num_voices) return S_OK; @@ -1756,40 +1761,37 @@ static HRESULT static_installed_voices_init(void) else all_voices.provider.num_voices = 1; + LeaveCriticalSection(&allvoices_cs); + return hr; } -/* - * - * IInstalledVoicesStatic for SpeechSynthesizer runtimeclass - * - */ +void static_installed_voices_deinit(void) +{ + UINT32 i; -DEFINE_IINSPECTABLE(installed_voices_static, IInstalledVoicesStatic, struct synthesizer_statics, IActivationFactory_iface) + EnterCriticalSection(&allvoices_cs); -static CRITICAL_SECTION allvoices_cs; -static CRITICAL_SECTION_DEBUG allvoices_critsect_debug = -{ - 0, 0, &allvoices_cs, - { &allvoices_critsect_debug.ProcessLocksList, &allvoices_critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": allvoices_cs") } -}; -static CRITICAL_SECTION allvoices_cs = { &allvoices_critsect_debug, -1, 0, 0, 0, 0 }; + for (i = 0; i < all_voices.provider.num_voices; ++i) + { + IVoiceInformation_Release(all_voices.provider.voices[i]); + all_voices.provider.voices[i] = NULL; + } + + LeaveCriticalSection(&allvoices_cs); + + all_voices.provider.num_voices = 0; +} static HRESULT WINAPI installed_voices_static_get_AllVoices( IInstalledVoicesStatic *iface, IVectorView_VoiceInformation **value ) { - HRESULT hr; - TRACE("iface %p, value %p.\n", iface, value); EnterCriticalSection(&allvoices_cs); - - if (SUCCEEDED(hr = static_installed_voices_init())) - IVectorView_VoiceInformation_AddRef((*value = &all_voices.IVectorView_VoiceInformation_iface)); - + IVectorView_VoiceInformation_AddRef((*value = &all_voices.IVectorView_VoiceInformation_iface)); LeaveCriticalSection(&allvoices_cs); - return hr; + return S_OK; } static HRESULT WINAPI installed_voices_static_get_DefaultVoice( IInstalledVoicesStatic *iface, IVoiceInformation **value ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10275
regardlng the last commit. To be properly thread safe, I'd rather: * keep the allocation done lazily (as it's currently done); you can protect against two threads allocating at the same time using: * alloc object * set the global variable with InterlockedCompareExchangePointer * and if another thread beats us, free the oject * for the process detach case,it would be better to implement DllCanUnloadNow (and keep track of the used objects) -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10275#note_131617
participants (2)
-
Bernhard Kölbl -
eric pouech (@epo)