Jacek Caban : netprofm: Implement connection points as the same object as their container.

Alexandre Julliard julliard at winehq.org
Sun Aug 20 00:02:29 CDT 2017


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Aug 18 14:43:24 2017 +0200

netprofm: Implement connection points as the same object as their container.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/netprofm/list.c       | 78 ++++++++++++++++++++++------------------------
 dlls/netprofm/tests/list.c | 20 ++++++++++--
 2 files changed, 55 insertions(+), 43 deletions(-)

diff --git a/dlls/netprofm/list.c b/dlls/netprofm/list.c
index d59ee0c..3f57284 100644
--- a/dlls/netprofm/list.c
+++ b/dlls/netprofm/list.c
@@ -75,6 +75,15 @@ struct connection
     VARIANT_BOOL           connected;
 };
 
+struct connection_point
+{
+    IConnectionPoint IConnectionPoint_iface;
+    IConnectionPointContainer *container;
+    IID iid;
+    struct list sinks;
+    DWORD cookie;
+};
+
 struct list_manager
 {
     INetworkListManager INetworkListManager_iface;
@@ -83,16 +92,9 @@ struct list_manager
     LONG                refs;
     struct list         networks;
     struct list         connections;
-};
-
-struct connection_point
-{
-    IConnectionPoint IConnectionPoint_iface;
-    IConnectionPointContainer *container;
-    LONG refs;
-    IID iid;
-    struct list sinks;
-    DWORD cookie;
+    struct connection_point list_mgr_cp;
+    struct connection_point cost_mgr_cp;
+    struct connection_point conn_mgr_cp;
 };
 
 struct sink_entry
@@ -146,21 +148,14 @@ static ULONG WINAPI connection_point_AddRef(
     IConnectionPoint *iface )
 {
     struct connection_point *cp = impl_from_IConnectionPoint( iface );
-    return InterlockedIncrement( &cp->refs );
+    return IConnectionPointContainer_AddRef( cp->container );
 }
 
 static ULONG WINAPI connection_point_Release(
     IConnectionPoint *iface )
 {
     struct connection_point *cp = impl_from_IConnectionPoint( iface );
-    LONG refs = InterlockedDecrement( &cp->refs );
-    if (!refs)
-    {
-        TRACE( "destroying %p\n", cp );
-        IConnectionPointContainer_Release( cp->container );
-        heap_free( cp );
-    }
-    return refs;
+    return IConnectionPointContainer_Release( cp->container );
 }
 
 static HRESULT WINAPI connection_point_GetConnectionInterface(
@@ -271,27 +266,16 @@ static const IConnectionPointVtbl connection_point_vtbl =
     connection_point_EnumConnections
 };
 
-static HRESULT connection_point_create(
-    IConnectionPoint **obj,
+static void connection_point_init(
+    struct connection_point *cp,
     REFIID riid,
     IConnectionPointContainer *container )
 {
-    struct connection_point *cp;
-    TRACE( "%p, %s, %p\n", obj, debugstr_guid(riid), container );
-
-    if (!(cp = heap_alloc( sizeof(*cp) ))) return E_OUTOFMEMORY;
     cp->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl;
     cp->container = container;
-    cp->refs = 1;
     cp->cookie = 0;
     cp->iid = *riid;
     list_init( &cp->sinks );
-
-    IConnectionPointContainer_AddRef( container );
-
-    *obj = &cp->IConnectionPoint_iface;
-    TRACE( "returning iface %p\n", *obj );
-    return S_OK;
 }
 
 static inline struct network *impl_from_INetwork(
@@ -1394,21 +1378,28 @@ static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPo
         REFIID riid, IConnectionPoint **cp)
 {
     struct list_manager *This = impl_from_IConnectionPointContainer( iface );
+    struct connection_point *ret;
 
     TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp );
 
     if (!riid || !cp)
         return E_POINTER;
 
-    if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ) ||
-        IsEqualGUID( riid, &IID_INetworkCostManagerEvents ) ||
-        IsEqualGUID( riid, &IID_INetworkConnectionEvents ))
-        return connection_point_create( cp, riid, iface );
-
-    FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
+    if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ))
+        ret = &This->list_mgr_cp;
+    else if (IsEqualGUID( riid, &IID_INetworkCostManagerEvents ))
+        ret = &This->cost_mgr_cp;
+    else if (IsEqualGUID( riid, &IID_INetworkConnectionEvents ))
+        ret = &This->conn_mgr_cp;
+    else
+    {
+        FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
+        *cp = NULL;
+        return E_NOINTERFACE;
+    }
 
-    *cp = NULL;
-    return E_NOINTERFACE;
+    IConnectionPoint_AddRef( *cp = &ret->IConnectionPoint_iface );
+    return S_OK;
 }
 
 static const struct IConnectionPointContainerVtbl cpc_vtbl =
@@ -1784,6 +1775,13 @@ HRESULT list_manager_create( void **obj )
     init_networks( mgr );
     mgr->refs = 1;
 
+    connection_point_init( &mgr->list_mgr_cp, &IID_INetworkListManagerEvents,
+                           &mgr->IConnectionPointContainer_iface );
+    connection_point_init( &mgr->cost_mgr_cp, &IID_INetworkCostManagerEvents,
+                           &mgr->IConnectionPointContainer_iface);
+    connection_point_init( &mgr->conn_mgr_cp, &IID_INetworkConnectionEvents,
+                           &mgr->IConnectionPointContainer_iface );
+
     *obj = &mgr->INetworkListManager_iface;
     TRACE( "returning iface %p\n", *obj );
     return S_OK;
diff --git a/dlls/netprofm/tests/list.c b/dlls/netprofm/tests/list.c
index 3937b2f..0a1f854 100644
--- a/dlls/netprofm/tests/list.c
+++ b/dlls/netprofm/tests/list.c
@@ -222,7 +222,7 @@ static void test_INetworkListManager( void )
     INetworkCostManager *cost_mgr;
     NLM_CONNECTIVITY connectivity;
     VARIANT_BOOL connected;
-    IConnectionPoint *pt;
+    IConnectionPoint *pt, *pt2;
     IEnumNetworks *network_iter;
     INetwork *network;
     IEnumNetworkConnections *conn_iter;
@@ -319,7 +319,10 @@ static void test_INetworkListManager( void )
     hr = IConnectionPoint_Unadvise( pt, cookie );
     ok( hr == S_OK, "Unadvise failed: %08x\n", hr );
 
-    IConnectionPoint_Release( pt );
+    hr = IConnectionPointContainer_FindConnectionPoint( cpc, &IID_INetworkListManagerEvents, &pt2 );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( pt == pt2, "pt != pt2\n");
+    IConnectionPoint_Release( pt2 );
 
     hr = IConnectionPointContainer_FindConnectionPoint( cpc, &IID_INetworkCostManagerEvents, &pt );
     ok( hr == S_OK || hr == CO_E_FAILEDTOIMPERSONATE, "got %08x\n", hr );
@@ -355,7 +358,18 @@ static void test_INetworkListManager( void )
         }
         IEnumNetworkConnections_Release( conn_iter );
     }
-    INetworkListManager_Release( mgr );
+
+    /* cps and their container share the same ref count */
+    IConnectionPoint_AddRef( pt );
+    IConnectionPoint_AddRef( pt );
+
+    ref1 = IConnectionPoint_Release( pt );
+    ref2 = INetworkListManager_Release( mgr );
+    ok( ref2 == ref1 - 1, "ref = %u\n", ref1 );
+
+    IConnectionPoint_Release( pt );
+    ref1 = IConnectionPoint_Release( pt );
+    ok( !ref1, "ref = %u\n", ref1 );
 }
 
 START_TEST( list )




More information about the wine-cvs mailing list