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 flag and simplify DirectSoundDevice_Release to free unconditionally. Signed-off-by: Jon Koops <jonkoops@gmail.com> --- dlls/dsound/dsound.c | 13 +++++-------- dlls/dsound/dsound_private.h | 3 +-- dlls/dsound/mixer.c | 33 ++++++++++++++------------------- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c index b5c53829a5b..c6b05516d32 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,14 +186,14 @@ static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice) return DS_OK; } -static ULONG DirectSoundDevice_Release(DirectSoundDevice * device) +static void DirectSoundDevice_destroy(DirectSoundDevice *device) { HRESULT hr; - ULONG ref = InterlockedDecrement(&(device->ref)); - TRACE("(%p) ref %ld\n", device, ref); - if (!ref) { int i; + TRACE("(%p)\n", device); + + InterlockedExchange(&device->terminated, TRUE); SetEvent(device->sleepev); if (device->thread) { WaitForSingleObject(device->thread, INFINITE); @@ -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) @@ -611,7 +608,7 @@ void DirectSoundDevice_RemoveBuffer(DirectSoundDevice * device, IDirectSoundBuff static void directsound_destroy(IDirectSoundImpl *This) { if (This->device) - DirectSoundDevice_Release(This->device); + DirectSoundDevice_destroy(This->device); TRACE("(%p) released\n", This); free(This); } diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 75279dacf87..a728472b7be 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -70,14 +70,13 @@ typedef struct DSFilter { */ struct DirectSoundDevice { - LONG ref; - GUID guid; DSCAPS drvcaps; DWORD priolevel, sleeptime; PWAVEFORMATEX pwfx, primary_pwfx; LPBYTE buffer; DWORD writelead, buflen, ac_frames, frag_frames, playpos, pad, stopped; + LONG terminated; int nrofbuffers; IDirectSoundBufferImpl** buffers; SRWLOCK buffer_list_lock; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 45e37c5bcb1..cb01fde468e 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -888,24 +888,19 @@ DWORD CALLBACK DSOUND_mixthread(void *p) 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); - if (ret == WAIT_FAILED) - WARN("wait returned error %lu %08lx!\n", GetLastError(), GetLastError()); - else if (ret != WAIT_OBJECT_0) - WARN("wait returned %08lx!\n", ret); - if (!dev->ref) - break; - - AcquireSRWLockShared(&dev->buffer_list_lock); - DSOUND_PerformMix(dev); - ReleaseSRWLockShared(&dev->buffer_list_lock); - } + for (;;) + { + DWORD ret = WaitForSingleObject(dev->sleepev, dev->sleeptime); + if (ret == WAIT_FAILED) + WARN("wait returned error %lu %08lx!\n", GetLastError(), GetLastError()); + else if (ret != WAIT_OBJECT_0) + WARN("wait returned %08lx!\n", ret); + if (dev->terminated) + break; + + AcquireSRWLockShared(&dev->buffer_list_lock); + DSOUND_PerformMix(dev); + ReleaseSRWLockShared(&dev->buffer_list_lock); + } return 0; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10919