From: Alexandre Julliard <julliard@winehq.org> --- dlls/mmdevapi/client.c | 46 +------------------------- dlls/mmdevapi/main.c | 2 +- dlls/mmdevapi/mmdevapi_private.h | 2 -- dlls/mmdevapi/unixlib.h | 27 +++++++++++---- dlls/winealsa.drv/alsa.c | 26 +++------------ dlls/winecoreaudio.drv/coreaudio.c | 26 +++------------ dlls/wineoss.drv/oss.c | 26 +++------------ dlls/winepulse.drv/pulse.c | 53 ++++++++++++++++++++---------- 8 files changed, 70 insertions(+), 138 deletions(-) diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index d7e05a68215..25ba520de48 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -42,16 +42,6 @@ typedef struct tagLANGANDCODEPAGE WORD wCodePage; } LANGANDCODEPAGE; -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; @@ -202,37 +192,6 @@ 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; @@ -503,10 +462,7 @@ static HRESULT stream_init(struct audio_client *client, const BOOLEAN force_def_ return AUDCLNT_E_ALREADY_INITIALIZED; } - if (FAILED(params.result = main_loop_start())) { - sessions_unlock(); - return params.result; - } + wine_unix_call( main_loop_start, NULL ); if (flags & AUDCLNT_STREAMFLAGS_LOOPBACK) { struct get_loopback_capture_device_params params; diff --git a/dlls/mmdevapi/main.c b/dlls/mmdevapi/main.c index 21b46b988f1..70eace863e1 100644 --- a/dlls/mmdevapi/main.c +++ b/dlls/mmdevapi/main.c @@ -211,7 +211,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) } if (lpvReserved) break; - main_loop_stop(); + wine_unix_call( main_loop_stop, NULL ); if (drvs.module_unixlib) { __wine_unload_unix_lib( drvs.module ); diff --git a/dlls/mmdevapi/mmdevapi_private.h b/dlls/mmdevapi/mmdevapi_private.h index acd3baa8cc4..6a04e9077ef 100644 --- a/dlls/mmdevapi/mmdevapi_private.h +++ b/dlls/mmdevapi/mmdevapi_private.h @@ -129,8 +129,6 @@ extern BOOL get_device_name_from_guid( const GUID *guid, char **name, EDataFlow extern HRESULT load_devices_from_reg(void); extern HRESULT load_driver_devices(EDataFlow flow); -extern void main_loop_stop(void); - extern const WCHAR drv_keyW[]; extern HRESULT get_audio_session(const GUID *sessionguid, IMMDevice *device, UINT channels, diff --git a/dlls/mmdevapi/unixlib.h b/dlls/mmdevapi/unixlib.h index 3df13e93b39..c46a4ff4e98 100644 --- a/dlls/mmdevapi/unixlib.h +++ b/dlls/mmdevapi/unixlib.h @@ -20,6 +20,25 @@ #include "audioclient.h" #include "mmdeviceapi.h" +#ifdef WINE_UNIX_LIB +/* helper to create a thread on the Unix side */ +static inline NTSTATUS create_unix_thread( HANDLE *handle, const WCHAR *name, + void (*entry)(void *), void *param ) +{ + DWORD priority = THREAD_PRIORITY_TIME_CRITICAL; + THREAD_NAME_INFORMATION info; + NTSTATUS status; + + if (!(status = PsCreateSystemThread( handle, THREAD_ALL_ACCESS, NULL, 0, NULL, entry, param ))) + { + RtlInitUnicodeString( &info.ThreadName, name ); + NtSetInformationThread( *handle, ThreadNameInformation, &info, sizeof(info) ); + NtSetInformationThread( *handle, ThreadBasePriority, &priority, sizeof(priority) ); + } + return status; +} +#endif + typedef UINT64 stream_handle; enum driver_priority @@ -36,11 +55,6 @@ struct endpoint unsigned int device; }; -struct main_loop_params -{ - HANDLE event; -}; - struct get_endpoint_ids_params { EDataFlow flow; @@ -315,7 +329,8 @@ enum unix_funcs { process_attach, process_detach, - main_loop, + main_loop_start, + main_loop_stop, get_endpoint_ids, create_stream, release_stream, diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c index e7c93116fd1..9497c06059c 100644 --- a/dlls/winealsa.drv/alsa.c +++ b/dlls/winealsa.drv/alsa.c @@ -477,13 +477,6 @@ 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}; @@ -2410,7 +2403,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { alsa_not_implemented, alsa_not_implemented, - alsa_main_loop, + alsa_not_implemented, + alsa_not_implemented, alsa_get_endpoint_ids, alsa_create_stream, alsa_release_stream, @@ -2462,19 +2456,6 @@ static NTSTATUS alsa_wow64_process_attach(void *args) return STATUS_SUCCESS; } -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 @@ -2876,7 +2857,8 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { alsa_wow64_process_attach, alsa_not_implemented, - alsa_wow64_main_loop, + alsa_not_implemented, + alsa_not_implemented, alsa_wow64_get_endpoint_ids, alsa_wow64_create_stream, alsa_wow64_release_stream, diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index a4f78f6d6bb..78acef1c004 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -199,13 +199,6 @@ 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; @@ -1774,7 +1767,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { unix_not_implemented, unix_not_implemented, - unix_main_loop, + unix_not_implemented, + unix_not_implemented, unix_get_endpoint_ids, unix_create_stream, unix_release_stream, @@ -1826,19 +1820,6 @@ static NTSTATUS unix_wow64_process_attach(void *args) return STATUS_SUCCESS; } -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 @@ -2239,7 +2220,8 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { unix_wow64_process_attach, unix_not_implemented, - unix_wow64_main_loop, + unix_not_implemented, + unix_not_implemented, unix_wow64_get_endpoint_ids, unix_wow64_create_stream, unix_wow64_release_stream, diff --git a/dlls/wineoss.drv/oss.c b/dlls/wineoss.drv/oss.c index 4136edf4fd8..23ac761570f 100644 --- a/dlls/wineoss.drv/oss.c +++ b/dlls/wineoss.drv/oss.c @@ -222,13 +222,6 @@ 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; @@ -1641,7 +1634,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { oss_not_implemented, oss_not_implemented, - oss_main_loop, + oss_not_implemented, + oss_not_implemented, oss_get_endpoint_ids, oss_create_stream, oss_release_stream, @@ -1709,19 +1703,6 @@ 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 @@ -2146,7 +2127,8 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { oss_wow64_process_attach, oss_not_implemented, - oss_wow64_main_loop, + oss_not_implemented, + oss_not_implemented, oss_wow64_get_endpoint_ids, oss_wow64_create_stream, oss_wow64_release_stream, diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index fdae8ecc36a..66a453e5a69 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -273,19 +273,47 @@ static void pulse_main_loop_thread_cleanup(void *context) pulse_broadcast(); } -static NTSTATUS pulse_main_loop(void *args) +static void pulse_main_loop(void *args) { - struct main_loop_params *params = args; + HANDLE event = args; int ret; pulse_lock(); pulse_ml = pa_mainloop_new(); pa_mainloop_set_poll_func(pulse_ml, pulse_poll_func, NULL); - NtSetEvent(params->event, NULL); + NtSetEvent(event, NULL); pthread_cleanup_push(pulse_main_loop_thread_cleanup, NULL); pa_mainloop_run(pulse_ml, &ret); pthread_cleanup_pop(0); pa_mainloop_free(pulse_ml); pulse_unlock(); + PsTerminateSystemThread( 0 ); +} + +static HANDLE main_loop_thread; + +static NTSTATUS pulse_main_loop_start(void *args) +{ + static const WCHAR name[] = {'a','u','d','i','o','_','c','l','i','e','n','t','_','m','a','i','n',0}; + HANDLE event; + NTSTATUS status; + + if (main_loop_thread) return STATUS_SUCCESS; + + NtCreateEvent( &event, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ); + if (!(status = create_unix_thread( &main_loop_thread, name, pulse_main_loop, event ))) + NtWaitForSingleObject( event, FALSE, NULL ); + NtClose( event ); + return status; +} + +static NTSTATUS pulse_main_loop_stop(void *args) +{ + if (main_loop_thread) + { + NtWaitForSingleObject( main_loop_thread, FALSE, NULL ); + NtClose( main_loop_thread ); + main_loop_thread = 0; + } return STATUS_SUCCESS; } @@ -2504,7 +2532,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { pulse_process_attach, pulse_process_detach, - pulse_main_loop, + pulse_main_loop_start, + pulse_main_loop_stop, pulse_get_endpoint_ids, pulse_create_stream, pulse_release_stream, @@ -2557,19 +2586,6 @@ static NTSTATUS pulse_wow64_process_attach(void *args) return pulse_process_attach( args ); } -static NTSTATUS pulse_wow64_main_loop(void *args) -{ - struct - { - PTR32 event; - } *params32 = args; - struct main_loop_params params = - { - .event = ULongToHandle(params32->event) - }; - return pulse_main_loop(¶ms); -} - static NTSTATUS pulse_wow64_get_endpoint_ids(void *args) { struct @@ -3011,7 +3027,8 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { pulse_wow64_process_attach, pulse_process_detach, - pulse_wow64_main_loop, + pulse_main_loop_start, + pulse_main_loop_stop, pulse_wow64_get_endpoint_ids, pulse_wow64_create_stream, pulse_wow64_release_stream, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10912