Michael Stefaniuc : dplayx: IDirectPlayLobby3 / IDirectPlayLobby3A have independent refcounts.

Alexandre Julliard julliard at winehq.org
Mon Apr 15 13:09:40 CDT 2013


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

Author: Michael Stefaniuc <mstefani at redhat.de>
Date:   Sat Apr 13 21:41:32 2013 +0200

dplayx: IDirectPlayLobby3 / IDirectPlayLobby3A have independent refcounts.

---

 dlls/dplayx/dplobby.c      |   81 +++++++++++++++++++++++---------------------
 dlls/dplayx/tests/dplayx.c |    2 +-
 2 files changed, 43 insertions(+), 40 deletions(-)

diff --git a/dlls/dplayx/dplobby.c b/dlls/dplayx/dplobby.c
index 12444cc..a0c11dd 100644
--- a/dlls/dplayx/dplobby.c
+++ b/dlls/dplayx/dplobby.c
@@ -83,7 +83,8 @@ typedef struct IDirectPlayLobbyImpl
 {
     IDirectPlayLobby3 IDirectPlayLobby3_iface;
     IDirectPlayLobby3A IDirectPlayLobby3A_iface;
-    LONG ulInterfaceRef;
+    LONG numIfaces; /* "in use interfaces" refcount */
+    LONG ref3, ref3A;
     CRITICAL_SECTION lock;
     DirectPlayLobbyData*          dpl;
 } IDirectPlayLobbyImpl;
@@ -152,40 +153,12 @@ static HRESULT WINAPI DPL_QueryInterface( IDirectPlayLobbyImpl *This, REFIID rii
   return S_OK;
 }
 
-/*
- * Simple procedure. Just increment the reference count to this
- * structure and return the new reference count.
- */
-static ULONG WINAPI DPL_AddRef( IDirectPlayLobbyImpl *This )
-{
-  ULONG ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
-
-  TRACE( "ref count incremented to %u for %p\n", ulInterfaceRefCount, This );
-
-  return ulInterfaceRefCount;
-}
-
-/*
- * Simple COM procedure. Decrease the reference count to this object.
- * If the object no longer has any reference counts, free up the associated
- * memory.
- */
-static ULONG WINAPI DPL_Release( IDirectPlayLobbyImpl *This )
+static void dplobby_destroy(IDirectPlayLobbyImpl *obj)
 {
-  ULONG ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
-
-  TRACE( "ref count decremented to %u for %p\n", ulInterfaceRefCount, This );
-
-  /* Deallocate if this is the last reference to the object */
-  if( ulInterfaceRefCount == 0 )
-  {
-     DPL_DestroyLobby1( This );
-     This->lock.DebugInfo->Spare[0] = 0;
-     DeleteCriticalSection( &This->lock );
-     HeapFree( GetProcessHeap(), 0, This );
-  }
-
-  return ulInterfaceRefCount;
+    DPL_DestroyLobby1( obj );
+    obj->lock.DebugInfo->Spare[0] = 0;
+    DeleteCriticalSection( &obj->lock );
+    HeapFree( GetProcessHeap(), 0, obj );
 }
 
 static HRESULT WINAPI IDirectPlayLobby3AImpl_QueryInterface( IDirectPlayLobby3A *iface, REFIID riid,
@@ -205,25 +178,53 @@ static HRESULT WINAPI IDirectPlayLobby3Impl_QueryInterface( IDirectPlayLobby3 *i
 static ULONG WINAPI IDirectPlayLobby3AImpl_AddRef(IDirectPlayLobby3A *iface)
 {
     IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
-    return DPL_AddRef( This );
+    ULONG ref = InterlockedIncrement( &This->ref3A );
+
+    TRACE( "(%p) ref3A=%d\n", This, ref );
+
+    if ( ref == 1 )
+        InterlockedIncrement( &This->numIfaces );
+
+    return ref;
 }
 
 static ULONG WINAPI IDirectPlayLobby3Impl_AddRef(IDirectPlayLobby3 *iface)
 {
     IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
-    return DPL_AddRef( This );
+    ULONG ref = InterlockedIncrement( &This->ref3 );
+
+    TRACE( "(%p) ref3=%d\n", This, ref );
+
+    if ( ref == 1 )
+        InterlockedIncrement( &This->numIfaces );
+
+    return ref;
 }
 
 static ULONG WINAPI IDirectPlayLobby3AImpl_Release(IDirectPlayLobby3A *iface)
 {
     IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface );
-    return DPL_Release( This );
+    ULONG ref = InterlockedDecrement( &This->ref3A );
+
+    TRACE( "(%p) ref3A=%d\n", This, ref );
+
+    if ( !ref && !InterlockedDecrement( &This->numIfaces ) )
+        dplobby_destroy( This );
+
+    return ref;
 }
 
 static ULONG WINAPI IDirectPlayLobby3Impl_Release(IDirectPlayLobby3 *iface)
 {
     IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface );
-    return DPL_Release( This );
+    ULONG ref = InterlockedDecrement( &This->ref3 );
+
+    TRACE( "(%p) ref3=%d\n", This, ref );
+
+    if ( !ref && !InterlockedDecrement( &This->numIfaces ) )
+        dplobby_destroy( This );
+
+    return ref;
 }
 
 
@@ -1520,7 +1521,9 @@ HRESULT dplobby_create( REFIID riid, void **ppv )
 
     obj->IDirectPlayLobby3_iface.lpVtbl = &dpl3_vt;
     obj->IDirectPlayLobby3A_iface.lpVtbl = &dpl3A_vt;
-    obj->ulInterfaceRef = 1;
+    obj->numIfaces = 1;
+    obj->ref3 = 1;
+    obj->ref3A = 0;
 
     InitializeCriticalSection( &obj->lock );
     obj->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectPlayLobbyImpl.lock");
diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c
index 6ed864c..991b3c6 100644
--- a/dlls/dplayx/tests/dplayx.c
+++ b/dlls/dplayx/tests/dplayx.c
@@ -6487,7 +6487,7 @@ static void test_COM_dplobby(void)
     hr = IDirectPlayLobby_QueryInterface(dpl, &IID_IDirectPlayLobbyA, (void**)&dplA);
     ok(hr == S_OK, "QueryInterface for IID_IDirectPlayLobbyA failed: %08x\n", hr);
     refcount = IDirectPlayLobby_AddRef(dplA);
-    todo_wine ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
+    ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
     IDirectPlayLobby_Release(dplA);
 
     hr = IDirectPlayLobby_QueryInterface(dpl, &IID_IDirectPlayLobby2, (void**)&dpl2);




More information about the wine-cvs mailing list