Module: wine Branch: master Commit: ba156ed28b7bc39e7bdce41e6afd9c458c2a6eb0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ba156ed28b7bc39e7bdce41e6a...
Author: Jacek Caban jacek@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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 )