Module: wine Branch: master Commit: c0565143f923f856bb30db06ddef33ac6dd2e9e3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c0565143f923f856bb30db06dd...
Author: Michael Stefaniuc mstefani@redhat.de Date: Wed Aug 31 01:13:33 2011 +0200
dsound: Don't delete the primary buffer if a sub iface is still in use.
---
dlls/dsound/dsound.c | 7 +++---- dlls/dsound/dsound_private.h | 1 + dlls/dsound/primary.c | 19 +++++++++++++------ dlls/dsound/sound3d.c | 17 ++++++++++------- 4 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c index d830c39..1c7b13f 100644 --- a/dlls/dsound/dsound.c +++ b/dlls/dsound/dsound.c @@ -1558,10 +1558,9 @@ HRESULT DirectSoundDevice_CreateSoundBuffer( device->dsbd.dwFlags |= DSBCAPS_LOCHARDWARE; else device->dsbd.dwFlags |= DSBCAPS_LOCSOFTWARE; hres = primarybuffer_create(device, &(device->primary), &(device->dsbd)); - if (device->primary) { - IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(device->primary)); - *ppdsb = (LPDIRECTSOUNDBUFFER)(device->primary); - } else + if (device->primary) + *ppdsb = (IDirectSoundBuffer*)&device->primary->IDirectSoundBuffer8_iface; + else WARN("primarybuffer_create() failed\n"); } } else { diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index e91fc35..43a800f 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -336,6 +336,7 @@ LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN; HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) DECLSPEC_HIDDEN; HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb, const DSBUFFERDESC *dsbd) DECLSPEC_HIDDEN; +void primarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
/* duplex.c */
diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index eaca2de..2e0a6a4 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -769,20 +769,26 @@ static ULONG WINAPI PrimaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER iface) IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface); ULONG ref = InterlockedIncrement(&(This->ref)); TRACE("(%p) ref was %d\n", This, ref - 1); + if(ref == 1) + InterlockedIncrement(&This->numIfaces); return ref; }
+void primarybuffer_destroy(IDirectSoundBufferImpl *This) +{ + This->device->primary = NULL; + HeapFree(GetProcessHeap(), 0, This); + TRACE("(%p) released\n", This); +} + static ULONG WINAPI PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER iface) { IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface); DWORD ref = InterlockedDecrement(&(This->ref)); TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) { - This->device->primary = NULL; - HeapFree(GetProcessHeap(), 0, This); - TRACE("(%p) released\n", This); - } + if (!ref && !InterlockedDecrement(&This->numIfaces)) + primarybuffer_destroy(This); return ref; }
@@ -1248,7 +1254,8 @@ HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl * return DSERR_OUTOFMEMORY; }
- dsb->ref = 0; + dsb->ref = 1; + dsb->numIfaces = 1; dsb->device = device; dsb->IDirectSoundBuffer8_iface.lpVtbl = (IDirectSoundBuffer8Vtbl *)&dspbvt;
diff --git a/dlls/dsound/sound3d.c b/dlls/dsound/sound3d.c index 0318420..a820c51 100644 --- a/dlls/dsound/sound3d.c +++ b/dlls/dsound/sound3d.c @@ -757,13 +757,9 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_QueryInterface( }
if ( IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) { - if (!This->device->primary) - primarybuffer_create(This->device, &This->device->primary, &This->device->dsbd); - if (This->device->primary) { - *ppobj = This->device->primary; - IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)*ppobj); - return S_OK; - } + *ppobj = &This->device->primary->IDirectSoundBuffer8_iface; + IDirectSoundBuffer8_AddRef(&This->device->primary->IDirectSoundBuffer8_iface); + return S_OK; }
FIXME( "Unknown IID %s\n", debugstr_guid( riid ) ); @@ -774,7 +770,12 @@ static ULONG WINAPI IDirectSound3DListenerImpl_AddRef(LPDIRECTSOUND3DLISTENER if { IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; ULONG ref = InterlockedIncrement(&(This->ref)); + TRACE("(%p) ref was %d\n", This, ref - 1); + + if(ref == 1) + InterlockedIncrement(&This->device->primary->numIfaces); + return ref; }
@@ -787,6 +788,8 @@ static ULONG WINAPI IDirectSound3DListenerImpl_Release(LPDIRECTSOUND3DLISTENER i if (!ref) { This->device->listener = 0; HeapFree(GetProcessHeap(), 0, This); + if (!InterlockedDecrement(&This->device->primary->numIfaces)) + primarybuffer_destroy(This->device->primary); TRACE("(%p) released\n", This); } return ref;