[complement-svn] SF.net SVN: complement: [1661] trunk/complement/explore/test/virtual_time
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2007-08-03 06:33:51
|
Revision: 1661 http://complement.svn.sourceforge.net/complement/?rev=1661&view=rev Author: complement Date: 2007-08-02 23:33:49 -0700 (Thu, 02 Aug 2007) Log Message: ----------- subscribe/unsubscribe operations for VTHandler Modified Paths: -------------- trunk/complement/explore/test/virtual_time/test/Makefile trunk/complement/explore/test/virtual_time/test/Makefile.inc trunk/complement/explore/test/virtual_time/test/unit_test.cc trunk/complement/explore/test/virtual_time/test/vt_operations.h trunk/complement/explore/test/virtual_time/vtime.cc trunk/complement/explore/test/virtual_time/vtime.h Added Paths: ----------- trunk/complement/explore/test/virtual_time/test/vt_handler.cc Modified: trunk/complement/explore/test/virtual_time/test/Makefile =================================================================== --- trunk/complement/explore/test/virtual_time/test/Makefile 2007-08-03 06:31:38 UTC (rev 1660) +++ trunk/complement/explore/test/virtual_time/test/Makefile 2007-08-03 06:33:49 UTC (rev 1661) @@ -14,9 +14,9 @@ LDFLAGS += -L${INSTALL_LIB_DIR} -Wl,-rpath=${INSTALL_LIB_DIR}:${STLPORT_LIB_DIR} -release-shared: PROJECT_LIBS = -lxmt -lsockios -lstem -lboost_regex -lexam -lboost_fs -dbg-shared: PROJECT_LIBS = -lxmtg -lsockiosg -lstemg -lboost_regexg -lexamg -lboost_fsg -stldbg-shared: PROJECT_LIBS = -lxmtstlg -lsockiosstlg -lstemstlg -lboost_regexstlg -lexamstlg -lboost_fsstlg +release-shared: PROJECT_LIBS = -lxmt -lsockios -lstem -lexam +dbg-shared: PROJECT_LIBS = -lxmtg -lsockiosg -lstemg -lexamg +stldbg-shared: PROJECT_LIBS = -lxmtstlg -lsockiosstlg -lstemstlg -lexamstlg LDLIBS = ${PROJECT_LIBS} Modified: trunk/complement/explore/test/virtual_time/test/Makefile.inc =================================================================== --- trunk/complement/explore/test/virtual_time/test/Makefile.inc 2007-08-03 06:31:38 UTC (rev 1660) +++ trunk/complement/explore/test/virtual_time/test/Makefile.inc 2007-08-03 06:33:49 UTC (rev 1661) @@ -7,6 +7,5 @@ vt_operations.cc \ VTmess_core.cc \ vt_object.cc \ - vt_dispatch.cc - - + vt_dispatch.cc \ + vt_handler.cc Modified: trunk/complement/explore/test/virtual_time/test/unit_test.cc =================================================================== --- trunk/complement/explore/test/virtual_time/test/unit_test.cc 2007-08-03 06:31:38 UTC (rev 1660) +++ trunk/complement/explore/test/virtual_time/test/unit_test.cc 2007-08-03 06:33:49 UTC (rev 1661) @@ -20,9 +20,12 @@ t.add( &vtime_operations::VTMess_core, vt_oper, "VTmess core transfer", tc[2] = t.add( &vtime_operations::gvt_add, vt_oper, "Group VT add", tc[1] ) ); - t.add( &vtime_operations::VTDispatch2, vt_oper, "VTDispatch2", - t.add( &vtime_operations::VTDispatch1, vt_oper, "VTDispatch1", - t.add( &vtime_operations::vt_object, vt_oper, "VT order", tc[2] ) ) ); + t.add( &vtime_operations::VTSubscription, vt_oper, "VTSubscription", + t.add( &vtime_operations::VTDispatch2, vt_oper, "VTHandler2", + t.add( &vtime_operations::VTDispatch2, vt_oper, "VTHandler1", + t.add( &vtime_operations::VTDispatch2, vt_oper, "VTDispatch2", + t.add( &vtime_operations::VTDispatch1, vt_oper, "VTDispatch1", + t.add( &vtime_operations::vt_object, vt_oper, "VT order", tc[2] ) ) ) ) ) ); return t.girdle(); } Added: trunk/complement/explore/test/virtual_time/test/vt_handler.cc =================================================================== --- trunk/complement/explore/test/virtual_time/test/vt_handler.cc (rev 0) +++ trunk/complement/explore/test/virtual_time/test/vt_handler.cc 2007-08-03 06:33:49 UTC (rev 1661) @@ -0,0 +1,177 @@ +// -*- C++ -*- Time-stamp: <07/07/26 09:53:24 ptr> + +#include "vt_operations.h" + +// #include <boost/lexical_cast.hpp> + +#include <iostream> +#include <vtime.h> + +using namespace vt; +using namespace std; + +class VTDummy : + public vt::VTHandler +{ + public: + VTDummy(); + VTDummy( stem::addr_type id ); + VTDummy( stem::addr_type id, const char *info ); + ~VTDummy(); + + void handler( const stem::Event& ); + void VTNewMember( const stem::Event& ); + + void wait(); + std::string msg; + int count; + + private: + xmt::condition cnd; + + DECLARE_RESPONSE_TABLE( VTDummy, vt::VTHandler ); +}; + +#define VT_MESS3 0x1203 + +VTDummy::VTDummy() : + VTHandler(), + count(0) +{ + cnd.set( false ); +} + +VTDummy::VTDummy( stem::addr_type id ) : + VTHandler( id ), + count(0) +{ + cnd.set( false ); +} + +VTDummy::VTDummy( stem::addr_type id, const char *info ) : + VTHandler( id, info ), + count(0) +{ + cnd.set( false ); +} + +VTDummy::~VTDummy() +{ + // cnd.wait(); +} + +void VTDummy::handler( const stem::Event& ev ) +{ + msg = ev.value(); + + cnd.set( true ); +} + +void VTDummy::VTNewMember( const stem::Event& ev ) +{ + // cerr << "Hello" << endl; + ++count; +} + +void VTDummy::wait() +{ + cnd.try_wait(); + + cnd.set( false ); +} + +DEFINE_RESPONSE_TABLE( VTDummy ) + EV_EDS( ST_NULL, VT_MESS3, handler ) +END_RESPONSE_TABLE + +int EXAM_IMPL(vtime_operations::VTHandler1) +{ + VTDummy dummy1; + VTDummy dummy2; + + stem::Event ev( VT_MESS3 ); + ev.dest( 0 ); // group + ev.value() = "hello"; + + dummy1.VTSend( ev ); + + dummy2.wait(); + + EXAM_CHECK( dummy2.msg == "hello" ); + EXAM_CHECK( dummy1.msg == "" ); + + return EXAM_RESULT; +} + +int EXAM_IMPL(vtime_operations::VTHandler2) +{ + VTDummy dummy1; + VTDummy dummy2; + VTDummy dummy3; + + stem::Event ev( VT_MESS3 ); + ev.dest( 0 ); // group + ev.value() = "hello"; + + dummy1.VTSend( ev ); + + dummy2.wait(); + dummy3.wait(); + + EXAM_CHECK( dummy3.count == 0 ); + EXAM_CHECK( dummy3.msg == "hello" ); + EXAM_CHECK( dummy2.count == 1 ); + EXAM_CHECK( dummy2.msg == "hello" ); + EXAM_CHECK( dummy1.count == 2 ); + EXAM_CHECK( dummy1.msg == "" ); + + ev.dest( 100 ); // not this group member + try { + dummy1.VTSend( ev ); + EXAM_ERROR( "exception expected" ); + } + catch ( std::domain_error& ) { + } + + return EXAM_RESULT; +} + +int EXAM_IMPL(vtime_operations::VTSubscription) +{ + VTDummy dummy1; + VTDummy dummy2; + + stem::Event ev( VT_MESS3 ); + ev.dest( 0 ); // group + ev.value() = "hello"; + + dummy1.VTSend( ev ); + + dummy2.wait(); + EXAM_CHECK( dummy2.msg == "hello" ); + + { + VTDummy dummy3; + + ev.value() = "hi"; + dummy1.VTSend( ev ); + + dummy2.wait(); + // dummy3.wait(); + + // EXAM_CHECK( dummy3.msg == "hi" ); + EXAM_CHECK( dummy3.msg == "" ); // dummy3 don't see, due to VTS + EXAM_CHECK( dummy2.msg == "hi" ); + EXAM_CHECK( dummy1.msg == "" ); + } + + ev.value() = "yet more"; + dummy1.VTSend( ev ); + + dummy2.wait(); + EXAM_CHECK( dummy2.msg == "yet more" ); + EXAM_CHECK( dummy1.msg == "" ); + + return EXAM_RESULT; +} + Modified: trunk/complement/explore/test/virtual_time/test/vt_operations.h =================================================================== --- trunk/complement/explore/test/virtual_time/test/vt_operations.h 2007-08-03 06:31:38 UTC (rev 1660) +++ trunk/complement/explore/test/virtual_time/test/vt_operations.h 2007-08-03 06:33:49 UTC (rev 1661) @@ -20,6 +20,11 @@ int EXAM_DECL(VTDispatch1); int EXAM_DECL(VTDispatch2); + + int EXAM_DECL(VTHandler1); + int EXAM_DECL(VTHandler2); + + int EXAM_DECL(VTSubscription); }; #endif // __vt_operations_h Modified: trunk/complement/explore/test/virtual_time/vtime.cc =================================================================== --- trunk/complement/explore/test/virtual_time/vtime.cc 2007-08-03 06:31:38 UTC (rev 1660) +++ trunk/complement/explore/test/virtual_time/vtime.cc 2007-08-03 06:33:49 UTC (rev 1661) @@ -405,6 +405,65 @@ vtstamp[grp][from] = vt.gvt[grp][from]; // my counter, as is, not delta } +bool vtime_obj_rec::rm_group( group_type g ) +{ + // strike out group g from my groups list + groups_container_type::iterator i = groups.find( g ); + if ( i == groups.end() ) { + throw domain_error( "VT object not member of group" ); + } + groups.erase( i ); + + // remove my VT component for group g + gvtime_type::iterator j = vt.gvt.find( g ); + + if ( j != vt.gvt.end() ) { + vt.gvt.erase( j ); + } + + // remove sended VT components for group g + for ( snd_delta_vtime_t::iterator k = svt.begin(); k != svt.end(); ++k ) { + gvtime_type::iterator l = k->second.find( g ); + if ( l != k->second.end() ) { + k->second.erase( l ); + } + } + + // remove recieved VT components for group g + for ( delta_vtime_type::iterator k = lvt.begin(); k != lvt.end(); ++k ) { + gvtime_type::iterator l = k->second.find( g ); + if ( l != k->second.end() ) { + k->second.erase( l ); + } + } + + // remove messages for group g that wait in delay pool + for ( dpool_t::iterator p = dpool.begin(); p != dpool.end(); ) { + if ( p->second->value().grp == g ) { + dpool.erase( p++ ); + } else { + ++p; + } + } + + return groups.empty() ? true : false; +} + +void vtime_obj_rec::rm_member( oid_type oid ) +{ + delta_vtime_type::iterator i = lvt.find( oid ); + + if ( i != lvt.end() ) { + lvt.erase( i ); + } + + snd_delta_vtime_t::iterator j = svt.find( oid ); + + if ( j != lvt.end() ) { + svt.erase( j ); + } +} + } // namespace detail void VTDispatcher::VTDispatch( const stem::Event_base<VTmess>& m ) @@ -521,10 +580,50 @@ void VTDispatcher::Subscribe( stem::addr_type addr, oid_type oid, group_type grp ) { + // See comment on top of VTSend above + xmt::recursive_scoped_lock lk( this->_theHistory_lock ); + + pair<gid_map_type::const_iterator,gid_map_type::const_iterator> range = + grmap.equal_range( grp ); + + for ( ; range.first != range.second; ++range.first ) { + vt_map_type::iterator i = vtmap.find( range.first->second ); + if ( i != vtmap.end() ) { + stem::Event ev( VTS_NEW_MEMBER ); + ev.dest( i->second.stem_addr() ); + ev.src( addr ); + Forward( ev ); + } + } + vtmap[oid].add( addr, grp ); grmap.insert( make_pair(grp,oid) ); } +void VTDispatcher::Unsubscribe( oid_type oid, group_type grp ) +{ + // See comment on top of VTSend above + xmt::recursive_scoped_lock lk( this->_theHistory_lock ); + + pair<gid_map_type::iterator,gid_map_type::iterator> range = + grmap.equal_range( grp ); + + while ( range.first != range.second ) { + if ( range.first->second == oid ) { + grmap.erase( range.first++ ); + } else { + ++range.first; + } + } + + vt_map_type::iterator i = vtmap.find( oid ); + if ( i != vtmap.end() ) { + if ( i->second.rm_group( grp ) ) { // no groups more + vtmap.erase( i ); + } + } +} + DEFINE_RESPONSE_TABLE( VTDispatcher ) EV_Event_base_T_( ST_NULL, MESS, VTDispatch, VTmess ) END_RESPONSE_TABLE @@ -583,7 +682,7 @@ void VTHandler::VTSend( const stem::Event& ev ) { ev.src( self_id() ); - // _vtdsp->VTSend( ev, grp ); + _vtdsp->VTSend( ev, ev.dest() ); // throw domain_error, if not group member } VTHandler::VTHandler() : @@ -591,26 +690,40 @@ { new( Init_buf ) Init(); - // _vtdsp->Subscribe( self_id(), ... , ... ); + _vtdsp->Subscribe( self_id(), oid_type( self_id() ), /* grp */ 0 ); } VTHandler::VTHandler( const char *info ) : EventHandler( info ) { new( Init_buf ) Init(); + + _vtdsp->Subscribe( self_id(), oid_type( self_id() ), /* grp */ 0 ); } VTHandler::VTHandler( stem::addr_type id, const char *info ) : EventHandler( id, info ) { new( Init_buf ) Init(); + + _vtdsp->Subscribe( id, oid_type( id ), /* grp */ 0 ); } VTHandler::~VTHandler() { + _vtdsp->Unsubscribe( oid_type( self_id() ), /* grp */ 0 ); + ((Init *)Init_buf)->~Init(); } +void VTHandler::VTNewMember( const stem::Event& ) +{ +} + +DEFINE_RESPONSE_TABLE( VTHandler ) + EV_EDS( ST_NULL, VTS_NEW_MEMBER, VTNewMember ) +END_RESPONSE_TABLE + } // namespace vt namespace std { Modified: trunk/complement/explore/test/virtual_time/vtime.h =================================================================== --- trunk/complement/explore/test/virtual_time/vtime.h 2007-08-03 06:31:38 UTC (rev 1660) +++ trunk/complement/explore/test/virtual_time/vtime.h 2007-08-03 06:33:49 UTC (rev 1661) @@ -38,7 +38,7 @@ namespace vt { typedef uint32_t vtime_unit_type; -typedef uint32_t group_type; +typedef stem::addr_type group_type; // required, used in VTSend typedef std::hash_map<oid_type, vtime_unit_type> vtime_type; bool operator <=( const vtime_type& l, const vtime_type& r ); @@ -186,6 +186,8 @@ { groups.insert(g); } void add( stem::addr_type a, group_type g ) { addr = a; groups.insert(g); } + bool rm_group( group_type ); + void rm_member( oid_type ); stem::addr_type stem_addr() const { return addr; } @@ -252,6 +254,7 @@ void VTSend( const stem::Event& e, group_type ); void Subscribe( stem::addr_type, oid_type, group_type ); + void Unsubscribe( oid_type, group_type ); private: typedef std::hash_map<oid_type, detail::vtime_obj_rec> vt_map_type; @@ -288,6 +291,7 @@ virtual ~VTHandler(); void VTSend( const stem::Event& e ); + virtual void VTNewMember( const stem::Event& e ); template <class D> void VTSend( const stem::Event_base<D>& e ) @@ -296,9 +300,12 @@ private: static class VTDispatcher *_vtdsp; + + DECLARE_RESPONSE_TABLE( VTHandler, stem::EventHandler ); }; #define MESS 0x300 +#define VTS_NEW_MEMBER 0x301 } // namespace vt This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |