-- v6: wineoss: Implement main_loop in unixlib. winecoreaudio: Implement main_loop in unixlib. winealsa: Implement main_loop in unixlib. winepulse: Move main loop logic into mmdevapi.
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/mmdevapi/client.c | 41 ++++++++++++++++++++++++++++++++ dlls/mmdevapi/main.c | 2 ++ dlls/mmdevapi/mmdevapi_private.h | 2 ++ dlls/winepulse.drv/mmdevdrv.c | 32 ++++--------------------- 4 files changed, 50 insertions(+), 27 deletions(-)
diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index bd861f8b890..b1b178e00a5 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -38,6 +38,16 @@ extern void sessions_unlock(void) DECLSPEC_HIDDEN;
extern struct audio_session_wrapper *session_wrapper_create(struct audio_client *client) DECLSPEC_HIDDEN;
+static HANDLE main_loop_thread; + +void main_loop_stop(void) +{ + if (main_loop_thread) { + WaitForSingleObject(main_loop_thread, INFINITE); + CloseHandle(main_loop_thread); + } +} + void set_stream_volumes(struct audio_client *This) { struct set_volumes_params params; @@ -114,6 +124,37 @@ static void dump_fmt(const WAVEFORMATEX *fmt) } }
+static DWORD CALLBACK main_loop_func(void *event) +{ + struct main_loop_params params; + + SetThreadDescription(GetCurrentThread(), L"audio_client_main"); + + params.event = event; + + WINE_UNIX_CALL(main_loop, ¶ms); + + return 0; +} + +HRESULT main_loop_start(void) +{ + if (!main_loop_thread) { + HANDLE event = CreateEventW(NULL, TRUE, FALSE, NULL); + if (!(main_loop_thread = CreateThread(NULL, 0, main_loop_func, event, 0, NULL))) { + ERR("Failed to create main loop thread\n"); + CloseHandle(event); + return E_FAIL; + } + + SetThreadPriority(main_loop_thread, THREAD_PRIORITY_TIME_CRITICAL); + WaitForSingleObject(event, INFINITE); + CloseHandle(event); + } + + return S_OK; +} + static DWORD CALLBACK timer_loop_func(void *user) { struct timer_loop_params params; diff --git a/dlls/mmdevapi/main.c b/dlls/mmdevapi/main.c index d3d4ec6a905..d1006b9999c 100644 --- a/dlls/mmdevapi/main.c +++ b/dlls/mmdevapi/main.c @@ -202,6 +202,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) WARN("Unable to deinitialize library: %lx\n", status); }
+ main_loop_stop(); + if (!lpvReserved) MMDevEnum_Free(); break; diff --git a/dlls/mmdevapi/mmdevapi_private.h b/dlls/mmdevapi/mmdevapi_private.h index 684d303eefb..5abde115951 100644 --- a/dlls/mmdevapi/mmdevapi_private.h +++ b/dlls/mmdevapi/mmdevapi_private.h @@ -80,4 +80,6 @@ extern HRESULT SpatialAudioClient_Create(IMMDevice *device, ISpatialAudioClient extern HRESULT load_devices_from_reg(void) DECLSPEC_HIDDEN; extern HRESULT load_driver_devices(EDataFlow flow) DECLSPEC_HIDDEN;
+extern void main_loop_stop(void) DECLSPEC_HIDDEN; + extern const WCHAR drv_keyW[] DECLSPEC_HIDDEN; diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 12e36fae827..f15fa88c15e 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -56,7 +56,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(pulse);
#define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
-static HANDLE pulse_thread; static struct list g_sessions = LIST_INIT(g_sessions); static struct list g_devices_cache = LIST_INIT(g_devices_cache);
@@ -115,11 +114,6 @@ BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, void *reserved)
LIST_FOR_EACH_ENTRY_SAFE(device, device_next, &g_devices_cache, struct device_cache, entry) free(device); - - if (pulse_thread) { - WaitForSingleObject(pulse_thread, INFINITE); - CloseHandle(pulse_thread); - } } return TRUE; } @@ -134,6 +128,8 @@ extern const IAudioClockVtbl AudioClock_Vtbl; extern const IAudioClock2Vtbl AudioClock2_Vtbl; extern const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl;
+extern HRESULT main_loop_start(void) DECLSPEC_HIDDEN; + extern struct audio_session_wrapper *session_wrapper_create( struct audio_client *client) DECLSPEC_HIDDEN;
@@ -157,15 +153,6 @@ static void pulse_release_stream(stream_handle stream, HANDLE timer) pulse_call(release_stream, ¶ms); }
-static DWORD CALLBACK pulse_mainloop_thread(void *event) -{ - struct main_loop_params params; - params.event = event; - SetThreadDescription(GetCurrentThread(), L"winepulse_mainloop"); - pulse_call(main_loop, ¶ms); - return 0; -} - typedef struct tagLANGANDCODEPAGE { WORD wLanguage; @@ -735,19 +722,10 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, return AUDCLNT_E_ALREADY_INITIALIZED; }
- if (!pulse_thread) + if (FAILED(hr = main_loop_start())) { - HANDLE event = CreateEventW(NULL, TRUE, FALSE, NULL); - if (!(pulse_thread = CreateThread(NULL, 0, pulse_mainloop_thread, event, 0, NULL))) - { - ERR("Failed to create mainloop thread.\n"); - sessions_unlock(); - CloseHandle(event); - return E_FAIL; - } - SetThreadPriority(pulse_thread, THREAD_PRIORITY_TIME_CRITICAL); - WaitForSingleObject(event, INFINITE); - CloseHandle(event); + sessions_unlock(); + return hr; }
params.name = name = get_application_name(TRUE);
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winealsa.drv/alsa.c | 24 ++++++++++++++++++++++-- dlls/winealsa.drv/mmdevdrv.c | 7 +++++++ 2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c index dbf85a7947e..4930850e9dc 100644 --- a/dlls/winealsa.drv/alsa.c +++ b/dlls/winealsa.drv/alsa.c @@ -476,6 +476,13 @@ static WCHAR *alsa_get_card_name(int card) return ret; }
+static NTSTATUS alsa_main_loop(void *args) +{ + struct main_loop_params *params = args; + NtSetEvent(params->event, NULL); + return STATUS_SUCCESS; +} + static NTSTATUS alsa_get_endpoint_ids(void *args) { static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0}; @@ -2493,7 +2500,7 @@ unixlib_entry_t __wine_unix_call_funcs[] = { alsa_not_implemented, alsa_not_implemented, - alsa_not_implemented, + alsa_main_loop, alsa_get_endpoint_ids, alsa_create_stream, alsa_release_stream, @@ -2531,6 +2538,19 @@ unixlib_entry_t __wine_unix_call_funcs[] =
typedef UINT PTR32;
+static NTSTATUS alsa_wow64_main_loop(void *args) +{ + struct + { + PTR32 event; + } *params32 = args; + struct main_loop_params params = + { + .event = ULongToHandle(params32->event) + }; + return alsa_main_loop(¶ms); +} + static NTSTATUS alsa_wow64_get_endpoint_ids(void *args) { struct @@ -2934,7 +2954,7 @@ unixlib_entry_t __wine_unix_call_wow64_funcs[] = { alsa_not_implemented, alsa_not_implemented, - alsa_not_implemented, + alsa_wow64_main_loop, alsa_wow64_get_endpoint_ids, alsa_wow64_create_stream, alsa_wow64_release_stream, diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c index 7c7096d584a..d2681fc8e9c 100644 --- a/dlls/winealsa.drv/mmdevdrv.c +++ b/dlls/winealsa.drv/mmdevdrv.c @@ -76,6 +76,8 @@ extern const IAudioClock2Vtbl AudioClock2_Vtbl; extern const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl; extern const IChannelAudioVolumeVtbl ChannelAudioVolume_Vtbl;
+extern HRESULT main_loop_start(void) DECLSPEC_HIDDEN; + extern struct audio_session_wrapper *session_wrapper_create( struct audio_client *client) DECLSPEC_HIDDEN;
@@ -598,6 +600,11 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, return AUDCLNT_E_ALREADY_INITIALIZED; }
+ if(FAILED(params.result = main_loop_start())){ + sessions_unlock(); + return params.result; + } + dump_fmt(fmt);
params.name = NULL;
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winecoreaudio.drv/coreaudio.c | 24 ++++++++++++++++++++++-- dlls/winecoreaudio.drv/mmdevdrv.c | 7 +++++++ 2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index d031b82583e..f41118e62f5 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -196,6 +196,13 @@ static BOOL device_has_channels(AudioDeviceID device, EDataFlow flow) return ret; }
+static NTSTATUS unix_main_loop(void *args) +{ + struct main_loop_params *params = args; + NtSetEvent(params->event, NULL); + return STATUS_SUCCESS; +} + static NTSTATUS unix_get_endpoint_ids(void *args) { struct get_endpoint_ids_params *params = args; @@ -1775,7 +1782,7 @@ unixlib_entry_t __wine_unix_call_funcs[] = { unix_not_implemented, unix_not_implemented, - unix_not_implemented, + unix_main_loop, unix_get_endpoint_ids, unix_create_stream, unix_release_stream, @@ -1813,6 +1820,19 @@ unixlib_entry_t __wine_unix_call_funcs[] =
typedef UINT PTR32;
+static NTSTATUS unix_wow64_main_loop(void *args) +{ + struct + { + PTR32 event; + } *params32 = args; + struct main_loop_params params = + { + .event = ULongToHandle(params32->event) + }; + return unix_main_loop(¶ms); +} + static NTSTATUS unix_wow64_get_endpoint_ids(void *args) { struct @@ -2157,7 +2177,7 @@ unixlib_entry_t __wine_unix_call_wow64_funcs[] = { unix_not_implemented, unix_not_implemented, - unix_not_implemented, + unix_wow64_main_loop, unix_wow64_get_endpoint_ids, unix_wow64_create_stream, unix_wow64_release_stream, diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c index f268e9565b4..300d2a8223a 100644 --- a/dlls/winecoreaudio.drv/mmdevdrv.c +++ b/dlls/winecoreaudio.drv/mmdevdrv.c @@ -70,6 +70,8 @@ static CRITICAL_SECTION_DEBUG g_sessions_lock_debug = static CRITICAL_SECTION g_sessions_lock = { &g_sessions_lock_debug, -1, 0, 0, 0, 0 }; static struct list g_sessions = LIST_INIT(g_sessions);
+extern HRESULT main_loop_start(void) DECLSPEC_HIDDEN; + extern struct audio_session_wrapper *session_wrapper_create( struct audio_client *client) DECLSPEC_HIDDEN;
@@ -587,6 +589,11 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, return AUDCLNT_E_ALREADY_INITIALIZED; }
+ if(FAILED(params.result = main_loop_start())){ + sessions_unlock(); + return params.result; + } + params.name = NULL; params.device = This->device_name; params.flow = This->dataflow;
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/wineoss.drv/mmdevdrv.c | 7 +++++++ dlls/wineoss.drv/oss.c | 24 ++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c index 12f10fd4377..038dcecd07f 100644 --- a/dlls/wineoss.drv/mmdevdrv.c +++ b/dlls/wineoss.drv/mmdevdrv.c @@ -82,6 +82,8 @@ extern const IAudioClock2Vtbl AudioClock2_Vtbl; extern const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl; extern const IChannelAudioVolumeVtbl ChannelAudioVolume_Vtbl;
+extern HRESULT main_loop_start(void) DECLSPEC_HIDDEN; + extern struct audio_session_wrapper *session_wrapper_create( struct audio_client *client) DECLSPEC_HIDDEN;
@@ -575,6 +577,11 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, return AUDCLNT_E_ALREADY_INITIALIZED; }
+ if(FAILED(params.result = main_loop_start())){ + sessions_unlock(); + return params.result; + } + params.name = NULL; params.device = This->device_name; params.flow = This->dataflow; diff --git a/dlls/wineoss.drv/oss.c b/dlls/wineoss.drv/oss.c index df03d3286d9..5049c711e98 100644 --- a/dlls/wineoss.drv/oss.c +++ b/dlls/wineoss.drv/oss.c @@ -221,6 +221,13 @@ static void get_default_device(EDataFlow flow, char device[OSS_DEVNODE_SIZE]) return; }
+static NTSTATUS oss_main_loop(void *args) +{ + struct main_loop_params *params = args; + NtSetEvent(params->event, NULL); + return STATUS_SUCCESS; +} + static NTSTATUS oss_get_endpoint_ids(void *args) { struct get_endpoint_ids_params *params = args; @@ -1684,7 +1691,7 @@ unixlib_entry_t __wine_unix_call_funcs[] = { oss_not_implemented, oss_not_implemented, - oss_not_implemented, + oss_main_loop, oss_get_endpoint_ids, oss_create_stream, oss_release_stream, @@ -1738,6 +1745,19 @@ static NTSTATUS oss_wow64_test_connect(void *args) return STATUS_SUCCESS; }
+static NTSTATUS oss_wow64_main_loop(void *args) +{ + struct + { + PTR32 event; + } *params32 = args; + struct main_loop_params params = + { + .event = ULongToHandle(params32->event) + }; + return oss_main_loop(¶ms); +} + static NTSTATUS oss_wow64_get_endpoint_ids(void *args) { struct @@ -2108,7 +2128,7 @@ unixlib_entry_t __wine_unix_call_wow64_funcs[] = { oss_not_implemented, oss_not_implemented, - oss_not_implemented, + oss_wow64_main_loop, oss_wow64_get_endpoint_ids, oss_wow64_create_stream, oss_wow64_release_stream,
Etaash Mathamsetty (@etaash.mathamsetty) commented about dlls/winecoreaudio.drv/mmdevdrv.c:
return AUDCLNT_E_ALREADY_INITIALIZED; }
- if(FAILED(params.result = main_loop_start())){
same here
Etaash Mathamsetty (@etaash.mathamsetty) commented about dlls/wineoss.drv/mmdevdrv.c:
return AUDCLNT_E_ALREADY_INITIALIZED; }
- if(FAILED(params.result = main_loop_start())){
same here
Etaash Mathamsetty (@etaash.mathamsetty) commented about dlls/winepulse.drv/mmdevdrv.c:
return AUDCLNT_E_ALREADY_INITIALIZED; }
- if (!pulse_thread)
- if (FAILED(hr = main_loop_start())) {
Once again, sorry for the nitpick, but why is the `{` on the next line here but in the same line in other places?
Etaash Mathamsetty (@etaash.mathamsetty) commented about dlls/winealsa.drv/mmdevdrv.c:
return AUDCLNT_E_ALREADY_INITIALIZED; }
- if(FAILED(params.result = main_loop_start())){
Sorry for the nitpick, but there should be a space after the if.
On Tue Jun 13 01:10:51 2023 +0000, Etaash Mathamsetty wrote:
Sorry for the nitpick, but there should be a space after the if.
I want to maintain the current file's code style, even if "wrong". The section is getting removed in the very next merge request anyway.
On Tue Jun 13 01:09:48 2023 +0000, Etaash Mathamsetty wrote:
same here
See above.
On Tue Jun 13 01:09:48 2023 +0000, Etaash Mathamsetty wrote:
Once again, sorry for the nitpick, but why is the `{` on the next line here but in the same line in other places?
See above.
On Tue Jun 13 01:09:48 2023 +0000, Etaash Mathamsetty wrote:
Sorry for the nitpick, but there should be a space after the if.
See above.
This merge request was approved by Huw Davies.