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