From: Jon Koops <jonkoops@gmail.com> With device sharing removed, each DirectSoundDevice has exactly one owner and no longer needs reference counting. Replace the ref field with a stop event that the mixer thread waits on alongside the existing sleep event using WaitForMultipleObjects, and simplify DirectSoundDevice_Release to free unconditionally. Signed-off-by: Jon Koops <jonkoops@gmail.com> --- dlls/dsound/dsound.c | 14 ++++++-------- dlls/dsound/dsound_private.h | 4 +--- dlls/dsound/mixer.c | 20 +++++++++----------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c index b5c53829a5b..53d08e02bed 100644 --- a/dlls/dsound/dsound.c +++ b/dlls/dsound/dsound.c @@ -134,7 +134,6 @@ static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice) return DSERR_OUTOFMEMORY; } - device->ref = 1; device->priolevel = DSSCL_NORMAL; device->stopped = 1; device->speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE); @@ -187,15 +186,14 @@ static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice) return DS_OK; } -static ULONG DirectSoundDevice_Release(DirectSoundDevice * device) +static void DirectSoundDevice_Release(DirectSoundDevice * device) { HRESULT hr; - ULONG ref = InterlockedDecrement(&(device->ref)); - TRACE("(%p) ref %ld\n", device, ref); - if (!ref) { int i; - SetEvent(device->sleepev); + TRACE("(%p)\n", device); + + SetEvent(device->stopev); if (device->thread) { WaitForSingleObject(device->thread, INFINITE); CloseHandle(device->thread); @@ -229,6 +227,7 @@ static ULONG DirectSoundDevice_Release(DirectSoundDevice * device) if(device->mmdevice) IMMDevice_Release(device->mmdevice); CloseHandle(device->sleepev); + CloseHandle(device->stopev); free(device->tmp_buffer); free(device->cp_buffer); free(device->buffer); @@ -236,8 +235,6 @@ static ULONG DirectSoundDevice_Release(DirectSoundDevice * device) DeleteCriticalSection(&device->mixlock); TRACE("(%p) released\n", device); free(device); - } - return ref; } static HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGUID lpcGUID) @@ -285,6 +282,7 @@ static HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGU device->mmdevice = mmdevice; device->guid = devGUID; device->sleepev = CreateEventW(0, 0, 0, 0); + device->stopev = CreateEventW(0, 0, 0, 0); device->buflen = ds_hel_buflen; hr = DSOUND_ReopenDevice(device, FALSE); diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 75279dacf87..fe89a10929a 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -70,8 +70,6 @@ typedef struct DSFilter { */ struct DirectSoundDevice { - LONG ref; - GUID guid; DSCAPS drvcaps; DWORD priolevel, sleeptime; @@ -105,7 +103,7 @@ struct DirectSoundDevice IAudioStreamVolume *volume; IAudioRenderClient *render; - HANDLE sleepev, thread; + HANDLE sleepev, stopev, thread; struct list entry; }; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 45e37c5bcb1..1c5e10434d7 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -883,25 +883,23 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) DWORD CALLBACK DSOUND_mixthread(void *p) { DirectSoundDevice *dev = p; + HANDLE handles[2] = { dev->stopev, dev->sleepev }; + DWORD ret; TRACE("(%p)\n", dev); SetThreadDescription(GetCurrentThread(), L"wine_dsound_mixer"); _controlfp_s(NULL, _DN_FLUSH, _MCW_DN); - while (dev->ref) { - DWORD ret; - - /* - * Some audio drivers are retarded and won't fire after being - * stopped, add a timeout to handle this. - */ - ret = WaitForSingleObject(dev->sleepev, dev->sleeptime); + /* + * Some audio drivers are retarded and won't fire after being + * stopped, add a timeout to handle this. + */ + while ((ret = WaitForMultipleObjects(ARRAY_SIZE(handles), handles, FALSE, dev->sleeptime)) != WAIT_OBJECT_0) + { if (ret == WAIT_FAILED) WARN("wait returned error %lu %08lx!\n", GetLastError(), GetLastError()); - else if (ret != WAIT_OBJECT_0) + else if (ret != WAIT_OBJECT_0 + 1) WARN("wait returned %08lx!\n", ret); - if (!dev->ref) - break; AcquireSRWLockShared(&dev->buffer_list_lock); DSOUND_PerformMix(dev); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10882