[PATCH 02/15] dsound: IDirectSoundCapture / IUnknown use separate refcounts.

Michael Stefaniuc mstefani at redhat.de
Wed Aug 15 18:21:26 CDT 2012


---
 dlls/dsound/capture.c        |  128 +++++++++++++++++++++++++++++++-----------
 dlls/dsound/dsound_private.h |    1 -
 2 files changed, 94 insertions(+), 35 deletions(-)

diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c
index 40df315..23668e9 100644
--- a/dlls/dsound/capture.c
+++ b/dlls/dsound/capture.c
@@ -995,67 +995,124 @@ static HRESULT DirectSoundCaptureDevice_Initialize(
 /*****************************************************************************
  * IDirectSoundCapture implementation structure
  */
-struct IDirectSoundCaptureImpl
+typedef struct IDirectSoundCaptureImpl
 {
+    IUnknown                 IUnknown_iface;  /* Separate refcount */
     IDirectSoundCapture      IDirectSoundCapture_iface;
-    LONG                     ref;
+    LONG                     ref, refdsc, numIfaces;
     DirectSoundCaptureDevice *device;
     BOOL                     has_dsc8;
-};
+} IDirectSoundCaptureImpl;
 
-static inline struct IDirectSoundCaptureImpl *impl_from_IDirectSoundCapture(IDirectSoundCapture *iface)
+static void capture_destroy(IDirectSoundCaptureImpl *This)
 {
-    return CONTAINING_RECORD(iface, struct IDirectSoundCaptureImpl, IDirectSoundCapture_iface);
+    if (This->device)
+        DirectSoundCaptureDevice_Release(This->device);
+    HeapFree(GetProcessHeap(),0,This);
+    TRACE("(%p) released\n", This);
 }
 
-/***************************************************************************
- * IDirectSoundCaptureImpl
+/*******************************************************************************
+ *      IUnknown Implementation for DirectSoundCapture
  */
-static HRESULT WINAPI IDirectSoundCaptureImpl_QueryInterface(IDirectSoundCapture *iface,
-        REFIID riid, void **ppobj)
+static inline IDirectSoundCaptureImpl *impl_from_IUnknown(IUnknown *iface)
 {
-    TRACE( "(%p,%s,%p)\n", iface, debugstr_guid(riid), ppobj );
+    return CONTAINING_RECORD(iface, IDirectSoundCaptureImpl, IUnknown_iface);
+}
 
-    if (ppobj == NULL) {
-	WARN("invalid parameter\n");
-	return E_INVALIDARG;
-    }
+static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
+{
+    IDirectSoundCaptureImpl *This = impl_from_IUnknown(iface);
 
-    *ppobj = NULL;
+    TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
 
-    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectSoundCapture)) {
-        IDirectSoundCapture_AddRef(iface);
-        *ppobj = iface;
-        return S_OK;
+    if (!ppv) {
+        WARN("invalid parameter\n");
+        return E_INVALIDARG;
     }
+    *ppv = NULL;
 
-    WARN("unsupported riid: %s\n", debugstr_guid(riid));
-    return E_NOINTERFACE;
+    if (IsEqualIID(riid, &IID_IUnknown))
+        *ppv = &This->IUnknown_iface;
+    else if (IsEqualIID(riid, &IID_IDirectSoundCapture))
+        *ppv = &This->IDirectSoundCapture_iface;
+    else {
+        WARN("unknown IID %s\n", debugstr_guid(riid));
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface)
+{
+    IDirectSoundCaptureImpl *This = impl_from_IUnknown(iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(ref == 1)
+        InterlockedIncrement(&This->numIfaces);
+    return ref;
+}
+
+static ULONG WINAPI IUnknownImpl_Release(IUnknown *iface)
+{
+    IDirectSoundCaptureImpl *This = impl_from_IUnknown(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if (!ref && !InterlockedDecrement(&This->numIfaces))
+        capture_destroy(This);
+    return ref;
+}
+
+static const IUnknownVtbl unk_vtbl =
+{
+    IUnknownImpl_QueryInterface,
+    IUnknownImpl_AddRef,
+    IUnknownImpl_Release
+};
+
+/***************************************************************************
+ * IDirectSoundCaptureImpl
+ */
+static inline struct IDirectSoundCaptureImpl *impl_from_IDirectSoundCapture(IDirectSoundCapture *iface)
+{
+    return CONTAINING_RECORD(iface, struct IDirectSoundCaptureImpl, IDirectSoundCapture_iface);
+}
+
+static HRESULT WINAPI IDirectSoundCaptureImpl_QueryInterface(IDirectSoundCapture *iface,
+        REFIID riid, void **ppv)
+{
+    IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
+    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
+    return IUnknown_QueryInterface(&This->IUnknown_iface, riid, ppv);
 }
 
 static ULONG WINAPI IDirectSoundCaptureImpl_AddRef(IDirectSoundCapture *iface)
 {
     IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
-    ULONG ref = InterlockedIncrement(&(This->ref));
+    ULONG ref = InterlockedIncrement(&This->refdsc);
 
-    TRACE("(%p) ref was %d\n", This, ref - 1);
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(ref == 1)
+        InterlockedIncrement(&This->numIfaces);
     return ref;
 }
 
 static ULONG WINAPI IDirectSoundCaptureImpl_Release(IDirectSoundCapture *iface)
 {
     IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
-    ULONG ref = InterlockedDecrement(&(This->ref));
-
-    TRACE("(%p) ref was %d\n", This, ref + 1);
+    ULONG ref = InterlockedDecrement(&This->refdsc);
 
-    if (!ref) {
-        if (This->device)
-            DirectSoundCaptureDevice_Release(This->device);
+    TRACE("(%p) ref=%d\n", This, ref);
 
-        HeapFree( GetProcessHeap(), 0, This );
-        TRACE("(%p) released\n", This);
-    }
+    if (!ref && !InterlockedDecrement(&This->numIfaces))
+        capture_destroy(This);
     return ref;
 }
 
@@ -1178,13 +1235,16 @@ static HRESULT IDirectSoundCaptureImpl_Create(REFIID riid, void **ppv, BOOL has_
 
     setup_dsound_options();
 
+    obj->IUnknown_iface.lpVtbl = &unk_vtbl;
     obj->IDirectSoundCapture_iface.lpVtbl = &dscvt;
     obj->ref = 1;
+    obj->refdsc = 0;
+    obj->numIfaces = 1;
     obj->device = NULL;
     obj->has_dsc8 = has_dsc8;
 
-    hr = IDirectSoundCapture_QueryInterface(&obj->IDirectSoundCapture_iface, riid, ppv);
-    IDirectSoundCapture_Release(&obj->IDirectSoundCapture_iface);
+    hr = IUnknown_QueryInterface(&obj->IUnknown_iface, riid, ppv);
+    IUnknown_Release(&obj->IUnknown_iface);
 
     return hr;
 }
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index 107cbab..c8498d3 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -40,7 +40,6 @@ extern int ds_default_bits_per_sample DECLSPEC_HIDDEN;
  * Predeclare the interface implementation structures
  */
 typedef struct IDirectSoundBufferImpl        IDirectSoundBufferImpl;
-typedef struct IDirectSoundCaptureImpl       IDirectSoundCaptureImpl;
 typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
 typedef struct DirectSoundDevice             DirectSoundDevice;
 typedef struct DirectSoundCaptureDevice      DirectSoundCaptureDevice;
-- 
1.7.6.5



More information about the wine-patches mailing list