Michael Stefaniuc : dsound: Don' t delete the primary buffer if a sub iface is still in use.

Alexandre Julliard julliard at winehq.org
Wed Aug 31 13:19:20 CDT 2011


Module: wine
Branch: master
Commit: c0565143f923f856bb30db06ddef33ac6dd2e9e3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c0565143f923f856bb30db06ddef33ac6dd2e9e3

Author: Michael Stefaniuc <mstefani at 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;




More information about the wine-cvs mailing list