dsound: Don't destroy primary buffer until device is released.
This commit is contained in:
parent
4d6ff85433
commit
f0be44c82d
|
@ -327,16 +327,22 @@ static ULONG WINAPI IDirectSoundBufferImpl_AddRef(IDirectSoundBuffer8 *iface)
|
||||||
static ULONG WINAPI IDirectSoundBufferImpl_Release(IDirectSoundBuffer8 *iface)
|
static ULONG WINAPI IDirectSoundBufferImpl_Release(IDirectSoundBuffer8 *iface)
|
||||||
{
|
{
|
||||||
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
|
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
|
||||||
ULONG ref = InterlockedDecrement(&This->ref);
|
ULONG ref;
|
||||||
|
|
||||||
TRACE("(%p) ref was %d\n", This, ref + 1);
|
if (is_primary_buffer(This)){
|
||||||
|
ref = capped_refcount_dec(&This->ref);
|
||||||
if (!ref && !InterlockedDecrement(&This->numIfaces)) {
|
if(!ref)
|
||||||
if (is_primary_buffer(This))
|
capped_refcount_dec(&This->numIfaces);
|
||||||
primarybuffer_destroy(This);
|
TRACE("(%p) ref is now: %d\n", This, ref);
|
||||||
else
|
return ref;
|
||||||
secondarybuffer_destroy(This);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ref = InterlockedDecrement(&This->ref);
|
||||||
|
if (!ref && !InterlockedDecrement(&This->numIfaces))
|
||||||
|
secondarybuffer_destroy(This);
|
||||||
|
|
||||||
|
TRACE("(%p) ref is now %d\n", This, ref);
|
||||||
|
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,16 +1083,22 @@ static ULONG WINAPI IKsPropertySetImpl_AddRef(IKsPropertySet *iface)
|
||||||
static ULONG WINAPI IKsPropertySetImpl_Release(IKsPropertySet *iface)
|
static ULONG WINAPI IKsPropertySetImpl_Release(IKsPropertySet *iface)
|
||||||
{
|
{
|
||||||
IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface);
|
IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface);
|
||||||
ULONG ref = InterlockedDecrement(&This->refiks);
|
ULONG ref;
|
||||||
|
|
||||||
TRACE("(%p) ref was %d\n", This, ref + 1);
|
if (is_primary_buffer(This)){
|
||||||
|
ref = capped_refcount_dec(&This->refiks);
|
||||||
if (!ref && !InterlockedDecrement(&This->numIfaces)) {
|
if(!ref)
|
||||||
if (is_primary_buffer(This))
|
capped_refcount_dec(&This->numIfaces);
|
||||||
primarybuffer_destroy(This);
|
TRACE("(%p) ref is now: %d\n", This, ref);
|
||||||
else
|
return ref;
|
||||||
secondarybuffer_destroy(This);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ref = InterlockedDecrement(&This->refiks);
|
||||||
|
if (!ref && !InterlockedDecrement(&This->numIfaces))
|
||||||
|
secondarybuffer_destroy(This);
|
||||||
|
|
||||||
|
TRACE("(%p) ref is now %d\n", This, ref);
|
||||||
|
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1255,11 +1255,6 @@ ULONG DirectSoundDevice_Release(DirectSoundDevice * device)
|
||||||
secondarybuffer_destroy(device->buffers[i]);
|
secondarybuffer_destroy(device->buffers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->primary) {
|
|
||||||
WARN("primary buffer not released\n");
|
|
||||||
IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)device->primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = DSOUND_PrimaryDestroy(device);
|
hr = DSOUND_PrimaryDestroy(device);
|
||||||
if (hr != DS_OK)
|
if (hr != DS_OK)
|
||||||
WARN("DSOUND_PrimaryDestroy failed\n");
|
WARN("DSOUND_PrimaryDestroy failed\n");
|
||||||
|
|
|
@ -288,6 +288,7 @@ HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl *
|
||||||
const DSBUFFERDESC *dsbd) DECLSPEC_HIDDEN;
|
const DSBUFFERDESC *dsbd) DECLSPEC_HIDDEN;
|
||||||
void primarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
|
void primarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
|
||||||
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
|
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
|
||||||
|
LONG capped_refcount_dec(LONG *ref) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* duplex.c */
|
/* duplex.c */
|
||||||
|
|
||||||
|
|
|
@ -258,6 +258,13 @@ HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device)
|
||||||
EnterCriticalSection(&(device->mixlock));
|
EnterCriticalSection(&(device->mixlock));
|
||||||
|
|
||||||
DSOUND_PrimaryClose(device);
|
DSOUND_PrimaryClose(device);
|
||||||
|
|
||||||
|
if(device->primary && (device->primary->ref || device->primary->numIfaces))
|
||||||
|
WARN("Destroying primary buffer while references held (%u %u)\n", device->primary->ref, device->primary->numIfaces);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, device->primary);
|
||||||
|
device->primary = NULL;
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(),0,device->pwfx);
|
HeapFree(GetProcessHeap(),0,device->pwfx);
|
||||||
device->pwfx=NULL;
|
device->pwfx=NULL;
|
||||||
|
|
||||||
|
@ -756,21 +763,31 @@ static ULONG WINAPI PrimaryBufferImpl_AddRef(IDirectSoundBuffer *iface)
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
void primarybuffer_destroy(IDirectSoundBufferImpl *This)
|
/* Decreases *out by 1 to no less than 0.
|
||||||
|
* Returns the new value of *out. */
|
||||||
|
LONG capped_refcount_dec(LONG *out)
|
||||||
{
|
{
|
||||||
This->device->primary = NULL;
|
LONG ref, oldref;
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
do {
|
||||||
TRACE("(%p) released\n", This);
|
ref = *out;
|
||||||
|
if(!ref)
|
||||||
|
return 0;
|
||||||
|
oldref = InterlockedCompareExchange(out, ref - 1, ref);
|
||||||
|
} while(oldref != ref);
|
||||||
|
return ref - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI PrimaryBufferImpl_Release(IDirectSoundBuffer *iface)
|
static ULONG WINAPI PrimaryBufferImpl_Release(IDirectSoundBuffer *iface)
|
||||||
{
|
{
|
||||||
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
|
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
|
||||||
DWORD ref = InterlockedDecrement(&(This->ref));
|
ULONG ref;
|
||||||
TRACE("(%p) ref was %d\n", This, ref + 1);
|
|
||||||
|
ref = capped_refcount_dec(&This->ref);
|
||||||
|
if(!ref)
|
||||||
|
capped_refcount_dec(&This->numIfaces);
|
||||||
|
|
||||||
|
TRACE("(%p) primary ref is now %d\n", This, ref);
|
||||||
|
|
||||||
if (!ref && !InterlockedDecrement(&This->numIfaces))
|
|
||||||
primarybuffer_destroy(This);
|
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -699,12 +699,13 @@ static ULONG WINAPI IDirectSound3DListenerImpl_AddRef(IDirectSound3DListener *if
|
||||||
static ULONG WINAPI IDirectSound3DListenerImpl_Release(IDirectSound3DListener *iface)
|
static ULONG WINAPI IDirectSound3DListenerImpl_Release(IDirectSound3DListener *iface)
|
||||||
{
|
{
|
||||||
IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
|
IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
|
||||||
ULONG ref = InterlockedDecrement(&This->ref3D);
|
ULONG ref;
|
||||||
|
|
||||||
TRACE("(%p) ref was %d\n", This, ref + 1);
|
ref = capped_refcount_dec(&This->ref3D);
|
||||||
|
if(!ref)
|
||||||
|
capped_refcount_dec(&This->numIfaces);
|
||||||
|
|
||||||
if (!ref && !InterlockedDecrement(&This->numIfaces))
|
TRACE("(%p) ref is now %d\n", This, ref);
|
||||||
primarybuffer_destroy(This);
|
|
||||||
|
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
|
@ -492,6 +492,15 @@ static HRESULT test_primary(LPGUID lpGuid)
|
||||||
test_buffer(dso,&primary,1,FALSE,0,FALSE,0,winetest_interactive &&
|
test_buffer(dso,&primary,1,FALSE,0,FALSE,0,winetest_interactive &&
|
||||||
!(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0,FALSE,0);
|
!(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0,FALSE,0);
|
||||||
|
|
||||||
|
ref=IDirectSoundBuffer_Release(primary);
|
||||||
|
ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references\n",ref);
|
||||||
|
|
||||||
|
ref=IDirectSoundBuffer_AddRef(primary);
|
||||||
|
ok(ref==1,"IDirectSoundBuffer_AddRef() primary has %d references\n",ref);
|
||||||
|
|
||||||
|
ref=IDirectSoundBuffer_Release(primary);
|
||||||
|
ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references\n",ref);
|
||||||
|
|
||||||
ref=IDirectSoundBuffer_Release(primary);
|
ref=IDirectSoundBuffer_Release(primary);
|
||||||
ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
|
ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
|
||||||
"should have 0\n",ref);
|
"should have 0\n",ref);
|
||||||
|
|
Loading…
Reference in New Issue