diff --git a/CEP/CPA/OCTOPUSSY/Makefile.am b/CEP/CPA/OCTOPUSSY/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..f5739da22320984d1e74fe5d0fb95657630bc4aa --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/Makefile.am @@ -0,0 +1,7 @@ +SUBDIRS=src test + +aids: + (cd src && make aids) + (cd test && make aids) + +include $(lofar_sharedir)/Makefile.common diff --git a/CEP/CPA/OCTOPUSSY/bootstrap b/CEP/CPA/OCTOPUSSY/bootstrap new file mode 100755 index 0000000000000000000000000000000000000000..06f18cde1dbfd6912ef7d927c4d35d25c7137a62 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/bootstrap @@ -0,0 +1,3 @@ +#!/bin/sh + +../../../autoconf_share/bootstrap ../../../autoconf_share diff --git a/CEP/CPA/OCTOPUSSY/configure.in b/CEP/CPA/OCTOPUSSY/configure.in new file mode 100644 index 0000000000000000000000000000000000000000..b59393fcc99ea5002383de271ac6171dd3bd7ee9 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/configure.in @@ -0,0 +1,70 @@ +dnl +dnl Process this file with autoconf to produce a configure script. +dnl +AC_INIT(src/Message.h) +dnl AC_CONFIG_AUX_DIR(config) +dnl AM_CONFIG_HEADER(config/config.h) +AM_CONFIG_HEADER(config.h) +AM_INIT_AUTOMAKE(OCTOPUSSY, 0.1) + +dnl Initialize for LOFAR (may set compilers) +lofar_INIT + +dnl Checks for programs. +AC_PROG_AWK +AC_PROG_YACC +AC_PROG_CC +AC_PROG_CXX +AM_PROG_LEX +AC_PROG_INSTALL +AC_PROG_LN_S +AC_DISABLE_SHARED +AM_PROG_LIBTOOL + +dnl Checks for libraries. + +dnl dnl Replace `main' with a function in -lfl: +dnl AC_CHECK_LIB(fl, main) +dnl dnl Replace `main' with a function in -lcosev_r: +dnl AC_CHECK_LIB(cosev_r, main) +dnl dnl Replace `main' with a function in -lcosnm_r: +dnl AC_CHECK_LIB(cosnm_r, main) +dnl dnl Replace `main' with a function in -lorb_r: +dnl AC_CHECK_LIB(orb_r, main) +dnl dnl Replace `main' with a function in -lpthread: +dnl AC_CHECK_LIB(pthread, main) +dnl dnl Replace `main' with a function in -lvport_r: +dnl AC_CHECK_LIB(vport_r, main) + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SIZE_T + +dnl Checks for library functions. +AC_FUNC_VPRINTF + +dnl +dnl Check for LOFAR specific things +dnl +lofar_DEBUG_OPTIMIZE +lofar_CORBA +dnl lofar_MATLAB +lofar_AIPSPP(1) +dnl lofar_MPI +lofar_QATOOLS +lofar_DOCXX +lofar_PACKAGE(DMI) + +dnl +dnl Output Makefiles +dnl +AC_OUTPUT( +src/Makefile +src/Glish/Makefile +test/Makefile +Makefile +) diff --git a/CEP/CPA/OCTOPUSSY/src/ConnectionMgrWP.cc b/CEP/CPA/OCTOPUSSY/src/ConnectionMgrWP.cc new file mode 100755 index 0000000000000000000000000000000000000000..12a71616e01cdd2679bf3ee2c0d443c7ba05ed07 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/ConnectionMgrWP.cc @@ -0,0 +1,33 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3CBDAC0A034E.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3CBDAC0A034E.cm + +//## begin module%3CBDAC0A034E.cp preserve=no +//## end module%3CBDAC0A034E.cp + +//## Module: ConnectionMgrWP%3CBDAC0A034E; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\ConnectionMgrWP.cc + +//## begin module%3CBDAC0A034E.additionalIncludes preserve=no +//## end module%3CBDAC0A034E.additionalIncludes + +//## begin module%3CBDAC0A034E.includes preserve=yes +//## end module%3CBDAC0A034E.includes + +// ConnectionMgrWP +#include "OCTOPUSSY/ConnectionMgrWP.h" +//## begin module%3CBDAC0A034E.declarations preserve=no +//## end module%3CBDAC0A034E.declarations + +//## begin module%3CBDAC0A034E.additionalDeclarations preserve=yes +//## end module%3CBDAC0A034E.additionalDeclarations + + +//## begin module%3CBDAC0A034E.epilog preserve=yes +//## end module%3CBDAC0A034E.epilog diff --git a/CEP/CPA/OCTOPUSSY/src/ConnectionMgrWP.h b/CEP/CPA/OCTOPUSSY/src/ConnectionMgrWP.h new file mode 100755 index 0000000000000000000000000000000000000000..d7c64f46e0f6a8ce7a132242796ad27e738a320c --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/ConnectionMgrWP.h @@ -0,0 +1,39 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3CBDAC0A033A.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3CBDAC0A033A.cm + +//## begin module%3CBDAC0A033A.cp preserve=no +//## end module%3CBDAC0A033A.cp + +//## Module: ConnectionMgrWP%3CBDAC0A033A; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\ConnectionMgrWP.h + +#ifndef ConnectionMgrWP_h +#define ConnectionMgrWP_h 1 + +//## begin module%3CBDAC0A033A.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3CBDAC0A033A.additionalIncludes + +//## begin module%3CBDAC0A033A.includes preserve=yes +//## end module%3CBDAC0A033A.includes + +//## begin module%3CBDAC0A033A.declarations preserve=no +//## end module%3CBDAC0A033A.declarations + +//## begin module%3CBDAC0A033A.additionalDeclarations preserve=yes +//## end module%3CBDAC0A033A.additionalDeclarations + + +//## begin module%3CBDAC0A033A.epilog preserve=yes +//## end module%3CBDAC0A033A.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/Dispatcher.cc b/CEP/CPA/OCTOPUSSY/src/Dispatcher.cc new file mode 100755 index 0000000000000000000000000000000000000000..fa15bfd4ad04adab87f2619ea238b3e6bd9632bb --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Dispatcher.cc @@ -0,0 +1,889 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7B7F30004B.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7B7F30004B.cm + +//## begin module%3C7B7F30004B.cp preserve=no +//## end module%3C7B7F30004B.cp + +//## Module: Dispatcher%3C7B7F30004B; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Dispatcher.cc + +//## begin module%3C7B7F30004B.additionalIncludes preserve=no +//## end module%3C7B7F30004B.additionalIncludes + +//## begin module%3C7B7F30004B.includes preserve=yes +#include <sys/time.h> +#include <errno.h> +#include <string.h> +#include "OCTOPUSSY/OctopussyConfig.h" +//## end module%3C7B7F30004B.includes + +// WPInterface +#include "OCTOPUSSY/WPInterface.h" +// Dispatcher +#include "OCTOPUSSY/Dispatcher.h" +//## begin module%3C7B7F30004B.declarations preserve=no +//## end module%3C7B7F30004B.declarations + +//## begin module%3C7B7F30004B.additionalDeclarations preserve=yes +// pulls in registry definitions +static int dum = aidRegistry_OCTOPUSSY(); + +Dispatcher * Dispatcher::dispatcher = 0; +sigset_t Dispatcher::raisedSignals,Dispatcher::allSignals; +struct sigaction * Dispatcher::orig_sigaction[_NSIG]; +bool Dispatcher::stop_polling = False; + +// static signal handler +void Dispatcher::signalHandler (int signum,siginfo_t *,void *) +{ + sigaddset(&raisedSignals,signum); + // if this signal is in the maps, increment its counters + pair<CSMI,CSMI> rng = dispatcher->signals.equal_range(signum); + for( CSMI iter = rng.first; iter != rng.second; iter++ ) + if( iter->second.counter ) + (*iter->second.counter)++; + // interrupt any poll loops + if( signum == SIGINT ) + stop_polling = True; +} +//## end module%3C7B7F30004B.additionalDeclarations + + +// Class Dispatcher + +Dispatcher::Dispatcher (AtomicID process, AtomicID host, int hz) + //## begin Dispatcher::Dispatcher%3C7CD444039C.hasinit preserve=no + //## end Dispatcher::Dispatcher%3C7CD444039C.hasinit + //## begin Dispatcher::Dispatcher%3C7CD444039C.initialization preserve=yes + : DebugContext("Dsp",&OctopussyDebugContext::getDebugContext()), + heartbeat_hz(hz), + config(OctopussyConfig::global()) + //## end Dispatcher::Dispatcher%3C7CD444039C.initialization +{ + //## begin Dispatcher::Dispatcher%3C7CD444039C.body preserve=yes + address = MsgAddress(AidDispatcher,0,process,host); + // init everything + init(); + //## end Dispatcher::Dispatcher%3C7CD444039C.body +} + +Dispatcher::Dispatcher (int hz) + //## begin Dispatcher::Dispatcher%3CD012B70209.hasinit preserve=no + //## end Dispatcher::Dispatcher%3CD012B70209.hasinit + //## begin Dispatcher::Dispatcher%3CD012B70209.initialization preserve=yes + : DebugContext("Dsp",&OctopussyDebugContext::getDebugContext()), + heartbeat_hz(hz), + config(OctopussyConfig::global()) + //## end Dispatcher::Dispatcher%3CD012B70209.initialization +{ + //## begin Dispatcher::Dispatcher%3CD012B70209.body preserve=yes + // check that required config items have been found + int hostid = 0; + if( !config.get("hostid",hostid) ) + dprintf(0)("warning: hostid not configured, using 1\n"); + // setup address + address = MsgAddress(AidDispatcher,0,getpid(),hostid); + init(); + //## end Dispatcher::Dispatcher%3CD012B70209.body +} + + +Dispatcher::~Dispatcher() +{ + //## begin Dispatcher::~Dispatcher%3C7B6A3E00A0_dest.body preserve=yes + if( running ) + stop(); + wps.clear(); + dispatcher = 0; + //## end Dispatcher::~Dispatcher%3C7B6A3E00A0_dest.body +} + + + +//## Other Operations (implementation) +void Dispatcher::init () +{ + //## begin Dispatcher::init%3CD014D00180.body preserve=yes + if( dispatcher ) + Throw("multiple Dispatchers initialized"); + dispatcher = this; + // set the log levels + int lev; + if( config.get("wploglevel",lev) || + config.getOption("lc",lev) || + config.getOption("l",lev) ) + WPInterface::setLogLevel(lev); + // set the frequency + config.get("hz",heartbeat_hz); + // init internals + memset(orig_sigaction,0,sizeof(orig_sigaction)); + sigemptyset(&raisedSignals); + sigemptyset(&allSignals); + running = in_start = False; + poll_depth = -1; + dprintf(1)("created\n"); + //## end Dispatcher::init%3CD014D00180.body +} + +const MsgAddress & Dispatcher::attach (WPRef &wpref) +{ + //## begin Dispatcher::attach%3C8CDDFD0361.body preserve=yes + FailWhen( !wpref.isWritable(),"writable ref required" ); + WPInterface & wp = wpref; + FailWhen( wp.isAttached() && wp.dsp() != this,"wp is already attached" ); + // assign instance number to this WP + AtomicID wpclass = wp.address().wpclass(); + int ninst = wp_instances[wpclass]++; + WPID wpid(wpclass,ninst); + wp.setAddress( MsgAddress(wpid,processId(),hostId()) ); + dprintf(1)("attaching WP: %s\n",wp.sdebug().c_str()); + wp.attach(this); + // if already starting up, then place attached wps onto a temp stack, + // to be attached later. + if( in_start ) + attached_wps.push(wpref); // let start handle it + else // add to map and activate + { + wps[wpid] = wpref; + if( running ) + { + wp.do_init(); + repoll |= wp.do_start(); + } + } + return wp.address(); + //## end Dispatcher::attach%3C8CDDFD0361.body +} + +const MsgAddress & Dispatcher::attach (WPInterface* wp, int flags) +{ + //## begin Dispatcher::attach%3C7B885A027F.body preserve=yes + WPRef ref(wp,flags|DMI::WRITE); + return attach(ref); + //## end Dispatcher::attach%3C7B885A027F.body +} + +void Dispatcher::detach (WPInterface* wp, bool delay) +{ + //## begin Dispatcher::detach%3C8CA2BD01B0.body preserve=yes + FailWhen( wp->dsp() != this, + "wp '"+wp->sdebug(1)+"' is not attached to this dispatcher"); + detach(wp->address().wpid(),delay); + //## end Dispatcher::detach%3C8CA2BD01B0.body +} + +void Dispatcher::detach (const WPID &id, bool delay) +{ + //## begin Dispatcher::detach%3C8CDE320231.body preserve=yes + WPI iter = wps.find(id); + FailWhen( iter == wps.end(), + "wpid '"+id.toString()+"' is not attached to this dispatcher"); + WPInterface *pwp = iter->second; + pwp->do_stop(); + // remove all events associated with this WP + for( TOILI iter = timeouts.begin(); iter != timeouts.end(); ) + if( iter->pwp == pwp ) + timeouts.erase(iter++); + else + iter++; + rebuildInputs(pwp); + rebuildSignals(pwp); + // if asked to delay, then move WP ref to delay stack, it will be + // detached later in poll() + if( delay ) + detached_wps.push(iter->second); + wps.erase(iter); + GWI iter2 = gateways.find(id); + if( iter2 != gateways.end() ) + gateways.erase(iter2); + //## end Dispatcher::detach%3C8CDE320231.body +} + +void Dispatcher::declareForwarder (WPInterface *wp) +{ + //## begin Dispatcher::declareForwarder%3C95C73F022A.body preserve=yes + CWPI iter = wps.find(wp->wpid()); + FailWhen( iter == wps.end() || iter->second.deref_p() != wp, + "WP not attached to this dispatcher"); + gateways[wp->wpid()] = wp; + //## end Dispatcher::declareForwarder%3C95C73F022A.body +} + +void Dispatcher::start () +{ + //## begin Dispatcher::start%3C7DFF770140.body preserve=yes + running = in_start = True; + in_pollLoop = False; + stop_polling = False; + tick = 0; + // say init to all WPs + dprintf(1)("starting\n"); + dprintf(2)("start: initializing WPs\n"); + for( WPI iter = wps.begin(); iter != wps.end(); iter++ ) + iter->second().do_init(); + // setup signal handler for SIGALRM + sigemptyset(&raisedSignals); + rebuildSignals(); + num_active_fds = 0; + rebuildInputs(); + // setup heartbeat timer + long period_usec = 1000000/heartbeat_hz; + // when stuck in a poll loop, do a select() at least this often: + inputs_poll_period = Timestamp(0,period_usec/2); + next_select = Timestamp::now(); + // start the timer + struct itimerval tval = { {0,period_usec},{0,period_usec} }; + setitimer(ITIMER_REAL,&tval,0); + // say start to all WPs + dprintf(2)("start: starting WPs\n"); + for( WPI iter = wps.begin(); iter != wps.end(); iter++ ) + repoll |= iter->second().do_start(); + in_start = False; + // if someone has launched any new WPs already, start them now + if( attached_wps.size() ) + { + dprintf(2)("start: initializing %d dynamically-added WPs\n",attached_wps.size()); + while( attached_wps.size() ) + { + WPRef &ref = attached_wps.top(); + ref().do_init(); + repoll |= ref().do_start(); + wps[ref->wpid()] = ref; + attached_wps.pop(); + } + } + dprintf(2)("start: complete\n"); + //## end Dispatcher::start%3C7DFF770140.body +} + +void Dispatcher::stop () +{ + //## begin Dispatcher::stop%3C7E0270027B.body preserve=yes + running = False; + dprintf(1)("stopping\n"); + // stop the heartbeat timer + struct itimerval tval = { {0,0},{0,0} }; + setitimer(ITIMER_REAL,&tval,0); + // tell all WPs that we are stopping + for( WPI iter = wps.begin(); iter != wps.end(); iter++ ) + iter->second().do_stop(); + // clear all event lists + timeouts.clear(); + inputs.clear(); + signals.clear(); + // this will effectively remove all signal handlers + rebuildSignals(); + //## end Dispatcher::stop%3C7E0270027B.body +} + +int Dispatcher::send (MessageRef &mref, const MsgAddress &to) +{ + //## begin Dispatcher::send%3C7B8867015B.body preserve=yes + int ndeliver = 0; + Message &msg = mref; + dprintf(2)("send(%s,%s)\n",msg.sdebug().c_str(),to.toString().c_str()); + // set the message to-address + msg.setTo(to); + // local delivery: check that host/process spec matches ours + if( to.host().matches(hostId()) && to.process().matches(processId()) ) + { + // addressed to specific wp class/instance? + AtomicID wpc = to.wpclass(),wpi=to.inst(); + if( !wildcardAddr(wpc) && !wildcardAddr(wpi) ) + { + WPI iter = wps.find(to.wpid()); // do we have that ID? + if( iter != wps.end() ) + { + dprintf(2)(" queing for: %s\n",iter->second->debug(1)); + // for first delivery, privatize the whole message & payload as read-only + if( !ndeliver ) + mref.privatize(DMI::READONLY|DMI::DEEP); + repoll |= iter->second().enqueue(mref.copy(),tick); + ndeliver++; + } + } + else // else it's a publish/b-cast: scan thru all WPs + { + for( WPI iter = wps.begin(); iter != wps.end(); iter++ ) + { + const MsgAddress & wpaddr = iter->second->address(); + if( wpc.matches(wpaddr.wpclass()) && wpi.matches(wpaddr.inst()) ) + { + dprintf(2)(" delivering to %s\n",iter->second->debug(1)); + } + else if( wpc == AidPublish && + iter->second->getSubscriptions().matches(msg) ) + { + dprintf(2)(" publishing to %s\n",iter->second->debug(1)); + } + else // else continue, so as to skip the deligvery below + continue; + // for first delivery, privatize the whole message & payload as read-only + if( !ndeliver ) + mref.privatize(DMI::READONLY|DMI::DEEP); + repoll |= iter->second().enqueue(mref.copy(),tick); + ndeliver++; + } + } + } + else + dprintf(2)(" destination address is not local\n"); + // If the message has a wider-than-local scope, then see if any gateways + // will take it + if( to.host() != hostId() || to.process() != processId() ) + { + for( GWI iter = gateways.begin(); iter != gateways.end(); iter++ ) + if( iter->second->willForward(msg) ) + { + dprintf(2)(" forwarding via %s\n",iter->second->debug(1)); + if( !ndeliver ) + mref.privatize(DMI::READONLY|DMI::DEEP); + repoll |= iter->second->enqueue(mref.copy(),tick); + ndeliver++; + } + } + if( !ndeliver ) + dprintf(2)("not delivered anywhere\n"); + return ndeliver; + //## end Dispatcher::send%3C7B8867015B.body +} + +void Dispatcher::poll () +{ + //## begin Dispatcher::poll%3C7B888E01CF.body preserve=yes + if( Debug(11) ) + { + static Timestamp last_poll; + Timestamp now; + Timestamp elapsed = now - last_poll; + dprintf(11)("entering poll() after %ld.%03ld ms\n", + elapsed.sec()*1000+elapsed.usec()/1000,elapsed.usec()%1000); + last_poll = now; + } + FailWhen(!running,"not running"); + // destroy all delay-detached WPs + if( !++poll_depth ) + while( detached_wps.size() ) + detached_wps.pop(); + // main polling loop + while( !stop_polling && ( checkEvents() || repoll ) ) + { + tick++; + // find max priority queue + int maxpri = -1; + WPInterface *maxwp = 0; + int num_repoll = 0; // # of WPs needing a repoll + // Find WP with maximum polling priority + // Count the number of WPs that required polling, too + for( WPI wpi = wps.begin(); wpi != wps.end(); wpi++ ) + { + WPInterface *pwp = wpi->second; + int pri = pwp->getPollPriority(tick); + if( pri >= 0 ) + { + num_repoll++; + if( pri >= maxpri ) + { + maxwp = pwp; + maxpri = pri; + } + } + } + // if more than 1 WP needs a repoll, force another loop + repoll = ( num_repoll > 1 ); + // deliver message, if a queue was found + if( maxwp ) + { + dprintf(3)("poll: max priority %d in %s, repoll=%d\n",maxpri,maxwp->debug(1),(int)repoll); + repoll |= maxwp->do_poll(tick); + } + } + --poll_depth; + //## end Dispatcher::poll%3C7B888E01CF.body +} + +void Dispatcher::pollLoop () +{ + //## begin Dispatcher::pollLoop%3C8C87AF031F.body preserve=yes + FailWhen(!running,"not running"); + FailWhen(in_pollLoop,"already in pollLoop()"); + in_pollLoop = True; + stop_polling = False; + rebuildSignals(); + // loop until a SIGINT + while( !sigismember(&raisedSignals,SIGINT) && !stop_polling ) + { + poll(); + // pause until next heartbeat (SIGALRM), or until an fd is active + if( max_fd >= 0 ) // use select(2) + { + fds_active = fds_watched; + num_active_fds = select(max_fd,&fds_active.r,&fds_active.w,&fds_active.x,NULL); + // we don't expect any errors except perhaps EINTR (interrupted by signal) + if( num_active_fds < 0 && errno != EINTR ) + dprintf(0)("select(): unexpected error %d (%s)\n",errno,strerror(errno)); + next_select = Timestamp::now() + inputs_poll_period; + } + else + pause(); // use plain pause(2) + } + in_pollLoop = False; + //## end Dispatcher::pollLoop%3C8C87AF031F.body +} + +void Dispatcher::stopPolling () +{ + //## begin Dispatcher::stopPolling%3CA09EB503C1.body preserve=yes + stop_polling = True; + //## end Dispatcher::stopPolling%3CA09EB503C1.body +} + +void Dispatcher::addTimeout (WPInterface* pwp, const Timestamp &period, const HIID &id, int flags, int priority) +{ + //## begin Dispatcher::addTimeout%3C7D28C30061.body preserve=yes + FailWhen(!period,"addTimeout: null period"); + // setup a new timeout structure + TimeoutInfo ti(pwp,id,priority); + ti.period = period; + ti.next = Timestamp() + period; + if( !next_to || ti.next < next_to ) + next_to = ti.next; + ti.flags = flags; + ti.id = id; + // add to list + timeouts.push_front(ti); + //## end Dispatcher::addTimeout%3C7D28C30061.body +} + +void Dispatcher::addInput (WPInterface* pwp, int fd, int flags, int priority) +{ + //## begin Dispatcher::addInput%3C7D28E3032E.body preserve=yes + FailWhen(fd<0,Debug::ssprintf("addInput: invalid fd %d",fd)); + FailWhen(!(flags&EV_FDALL),"addInput: no fd flags specified"); + // check if perhaps this fd is already being watched, then we only need to + // add to the flags + for( IILI iter = inputs.begin(); iter != inputs.end(); iter++ ) + { + if( iter->pwp == pwp && iter->fd == fd ) + { + iter->flags = flags | (iter->flags&EV_FDALL); + iter->msg().setPriority(priority); + rebuildInputs(); + return; + } + } + // else setup a new input structure + InputInfo ii(pwp,AtomicID(fd),priority); + ii.fd = fd; + ii.flags = flags; + // add to list + inputs.push_front(ii); + // rebuild input sets + rebuildInputs(); + //## end Dispatcher::addInput%3C7D28E3032E.body +} + +void Dispatcher::addSignal (WPInterface* pwp, int signum, int flags, volatile int* counter, int priority) +{ + //## begin Dispatcher::addSignal%3C7DFF4A0344.body preserve=yes + FailWhen(signum<0,Debug::ssprintf("addSignal: invalid signal %d",signum)); + // look at map for this signal to see if this WP is already registered + for( SMI iter = signals.lower_bound(signum); + iter->first == signum && iter != signals.end(); iter++ ) + { + if( iter->second.pwp == pwp ) // found it? change priority & return + { + iter->second.msg().setPriority(priority); + return; + } + } + // insert WP into map + SignalInfo si(pwp,AtomicID(signum),priority); + si.signum = signum; + si.flags = flags; + si.counter = counter; + si.msg().setState(0); + signals.insert( SMPair(signum,si) ); + rebuildSignals(); + //## end Dispatcher::addSignal%3C7DFF4A0344.body +} + +bool Dispatcher::removeTimeout (WPInterface* pwp, const HIID &id) +{ + //## begin Dispatcher::removeTimeout%3C7D28F202F3.body preserve=yes + for( TOILI iter = timeouts.begin(); iter != timeouts.end(); ) + { + if( iter->pwp == pwp && id.matches(iter->id) ) + { + // remove any remaining timeout messages from this queue + repoll |= pwp->dequeue(iter->msg->id()); + timeouts.erase(iter++); + return True; + } + else + iter++; + } + return False; + //## end Dispatcher::removeTimeout%3C7D28F202F3.body +} + +bool Dispatcher::removeInput (WPInterface* pwp, int fd, int flags) +{ + //## begin Dispatcher::removeInput%3C7D2947002F.body preserve=yes + if( fd<0 ) // fd<0 means remove everything + flags = ~0; + for( IILI iter = inputs.begin(); iter != inputs.end(); iter++ ) + { + // is an input message sitting intill undelivered? + // (WPInterface::poll() will reset its state to 0 when delivered) + // input messages are dequeued/modified inside WorkProcess::removeInput. + if( iter->pwp == pwp && (fd<0 || iter->fd == fd) ) + { + // is an input message sitting in the queue, undelivered? Clear its flags + MessageRef & ref = iter->last_msg; + if( ref.valid() && ref.isWritable() && ref->state() ) + ref().setState(ref->state()&~flags); + // clear flags of input + if( ( iter->flags &= ~flags ) == 0 ) // removed all modes? + inputs.erase(iter); + rebuildInputs(); + return True; + } + } + return False; + //## end Dispatcher::removeInput%3C7D2947002F.body +} + +bool Dispatcher::removeSignal (WPInterface* pwp, int signum) +{ + //## begin Dispatcher::removeSignal%3C7DFF57025C.body preserve=yes + bool res = False; + pair<SMI,SMI> rng; + // if signum<0, removes all signals for this WP + if( signum<0 ) + rng = pair<SMI,SMI>(signals.begin(),signals.end()); // range = all signals + else + rng = signals.equal_range(signum); // range = this signal's entries + // iterate over the range + for( SMI iter = rng.first; iter != rng.second; ) + { + if( iter->second.pwp == pwp ) + { + signals.erase(iter++); + res = True; + } + else + iter++; + } + // remove any pending messages from WP's queue + HIID id = AidEvent|AidSignal|AtomicID(signum); + if( signum<0 ) + id[2] = AidWildcard; + repoll |= pwp->dequeue(id); + + if( res ) + rebuildSignals(); + + return res; + //## end Dispatcher::removeSignal%3C7DFF57025C.body +} + +Dispatcher::WPIter Dispatcher::initWPIter () +{ + //## begin Dispatcher::initWPIter%3C98D4530076.body preserve=yes + return wps.begin(); + //## end Dispatcher::initWPIter%3C98D4530076.body +} + +bool Dispatcher::getWPIter (Dispatcher::WPIter &iter, WPID &wpid, const WPInterface *&pwp) +{ + //## begin Dispatcher::getWPIter%3C98D47B02B9.body preserve=yes + if( iter == wps.end() ) + return False; + wpid = iter->first; + pwp = iter->second.deref_p(); + iter++; + return True; + //## end Dispatcher::getWPIter%3C98D47B02B9.body +} + +void Dispatcher::addLocalData (const HIID &id, ObjRef ref) +{ + //## begin Dispatcher::addLocalData%3CBEDDD8001A.body preserve=yes + FailWhen( localData_[id].exists(),id.toString()+" is already defined in local data"); + localData_[id] <<= ref; + //## end Dispatcher::addLocalData%3CBEDDD8001A.body +} + +DataField & Dispatcher::addLocalData (const HIID &id) +{ + //## begin Dispatcher::addLocalData%3CBEE41702F4.body preserve=yes + FailWhen( localData_[id].exists(),id.toString()+" is already defined in local data"); + DataField *field = new DataField; + localData_[id] <<= field; + return *field; + //## end Dispatcher::addLocalData%3CBEE41702F4.body +} + +NestableContainer::Hook Dispatcher::localData (const HIID &id) +{ + //## begin Dispatcher::localData%3CC405480057.body preserve=yes + return localData_[id]; + //## end Dispatcher::localData%3CC405480057.body +} + +bool Dispatcher::hasLocalData (const HIID &id) +{ + //## begin Dispatcher::hasLocalData%3CC00549020D.body preserve=yes + return localData_[id].exists(); + //## end Dispatcher::hasLocalData%3CC00549020D.body +} + +// Additional Declarations + //## begin Dispatcher%3C7B6A3E00A0.declarations preserve=yes +void Dispatcher::rebuildInputs (WPInterface *remove) +{ + FD_ZERO(&fds_watched.r); + FD_ZERO(&fds_watched.w); + FD_ZERO(&fds_watched.x); + max_fd = -1; + for( IILI iter = inputs.begin(); iter != inputs.end(); ) + { + if( remove && iter->pwp == remove ) + inputs.erase(iter++); + else + { + if( iter->flags&EV_FDREAD ) + FD_SET(iter->fd,&fds_watched.r); + if( iter->flags&EV_FDWRITE ) + FD_SET(iter->fd,&fds_watched.w); + if( iter->flags&EV_FDEXCEPTION ) + FD_SET(iter->fd,&fds_watched.x); + if( iter->fd > max_fd ) + max_fd = iter->fd; + iter++; + } + } + if( max_fd >=0 ) + max_fd++; // this is the 'n' argument to select(2) +} + +void Dispatcher::rebuildSignals (WPInterface *remove) +{ + // rebuild mask of handled signals + sigset_t newmask; + sigemptyset(&newmask); + if( running ) + sigaddset(&newmask,SIGALRM); // ALRM handled when running + if( in_pollLoop ) + sigaddset(&newmask,SIGINT); // INT handled in pollLoop + int sig0 = -1; + for( SMI iter = signals.begin(); iter != signals.end(); ) + { + if( remove && iter->second.pwp == remove ) + signals.erase(iter++); + else + { + if( iter->first != sig0 ) + sigaddset(&newmask,sig0=iter->first); + iter++; + } + } + // init a sigaction structure + struct sigaction sa; + sa.sa_handler = 0; + sa.sa_sigaction = Dispatcher::signalHandler; + sa.sa_mask = newmask; + sa.sa_flags = SA_SIGINFO; + // go thru all signals + for( int sig = 0; sig < _NSIG; sig++ ) + { + bool newsig = sigismember(&newmask,sig), + oldsig = sigismember(&allSignals,sig); + if( newsig && !oldsig ) // start handling signal? + { + Assert(!orig_sigaction[sig]); // to store old handler + orig_sigaction[sig] = new struct sigaction; + sigaction(sig,&sa,orig_sigaction[sig]); + } + else if( !newsig && oldsig ) // stop handling? + { + Assert(orig_sigaction[sig]); + sigaction(sig,0,orig_sigaction[sig]); // reset old handler + delete orig_sigaction[sig]; + orig_sigaction[sig] = 0; + } + } + allSignals = newmask; +} + +bool Dispatcher::checkEvents() +{ + // ------ check timeouts + // next_to gives us the timestamp of the nearest timeout + Timestamp now; + if( next_to && next_to <= now ) + { + next_to = 0; + // see which timeouts are up, and update next_to as well + for( TOILI iter = timeouts.begin(); iter != timeouts.end(); ) + { + if( iter->next <= now ) // this timeout has fired? + { + repoll |= iter->pwp->enqueue( iter->msg.copy(DMI::READONLY),tick ); + if( iter->flags&EV_ONESHOT ) // not continouos? clear it now + { + timeouts.erase(iter++); + continue; + } + // else continous, so set the next timestamp + iter->next = now + iter->period; + } + if( !next_to || iter->next < next_to ) + next_to = iter->next; + iter++; + } + } + // ------ check inputs + // while in Dispatcher::pollLoop(), select() is already being done for + // us. Check the fds otherwise + if( inputs.size() && now >= next_select ) + { + struct timeval to = {0,0}; // select will return immediately + fds_active = fds_watched; + num_active_fds = select(max_fd,&fds_active.r,&fds_active.w,&fds_active.x,&to); + // we don't expect any errors except perhaps EINTR (interrupted by signal) + if( num_active_fds < 0 && errno != EINTR ) + dprintf(0)("select(): unexpected error %d (%s)\n",errno,strerror(errno)); + next_select = now + inputs_poll_period; + } + if( num_active_fds>0 ) + { + // iterate over all inputs + for( IILI iter = inputs.begin(); iter != inputs.end(); ) + { + // set local flags var according to state of fd + int flags = 0; + if( iter->flags&EV_FDREAD && FD_ISSET(iter->fd,&fds_active.r) ) + flags |= EV_FDREAD; + if( iter->flags&EV_FDWRITE && FD_ISSET(iter->fd,&fds_active.w) ) + flags |= EV_FDWRITE; + if( iter->flags&EV_FDEXCEPTION && FD_ISSET(iter->fd,&fds_active.x) ) + flags |= EV_FDEXCEPTION; + // anything raised? + if( flags ) + { + MessageRef & ref = iter->last_msg; + // is a previous message still undelivered? + // (WPInterface::poll() will reset its state to 0 when delivered) + if( ref.valid() && ref->state() != 0 ) + { + ref().setState(ref->state()|flags); // update state + // is this same message at the head of the queue? repoll then + const WPInterface::QueueEntry *qe = iter->pwp->topOfQueue(); + if( qe && qe->mref == ref ) + { + repoll = True; + iter->pwp->setNeedRepoll(True); + } + } + else // not found, so enqueue a message + { + // make a writable copy of the template message, because we set state + ref = iter->msg.copy().privatize(DMI::WRITE); + ref().setState(flags); + repoll |= iter->pwp->enqueue(ref.copy(DMI::WRITE),tick); + } + // if event is one-shot, clear it + if( iter->flags&EV_ONESHOT ) + { + inputs.erase(iter++); + continue; + } + } + iter++; + } + // clear active fds + num_active_fds = 0; + } + // ------ check signals + // grab & flush the current raised-mask + sigset_t mask = raisedSignals; + sigemptyset(&raisedSignals); + // go through all raised signals + for( int sig = 0; sig < _NSIG; sig++ ) + { + if( sigismember(&mask,sig) ) // signal raised? See who wants it + { + pair<SMI,SMI> rng = signals.equal_range(sig); + for( SMI iter = rng.first; iter != rng.second; ) + { + // no message generated for EV_IGNORE + if( !(iter->second.flags&EV_IGNORE) ) + { + // discrete signal events requested, so always enqueue a message + if( iter->second.flags&EV_DISCRETE ) + { + repoll |= iter->second.pwp->enqueue(iter->second.msg.copy(DMI::WRITE),tick); + } + else // else see if event is already enqueued & not delivered + { + // is a previous message still undelivered? + // (WPInterface::poll() will reset its state to 0 when delivered) + if( iter->second.msg->state() ) + { + // simply ask for a repoll if the message is at top of queue + const WPInterface::QueueEntry *qe = iter->second.pwp->topOfQueue(); + if( qe && qe->mref == iter->second.msg ) + iter->second.pwp->setNeedRepoll(repoll=True); + } + else // not in queue anymore, so enqueue a message + { + iter->second.msg().setState(1); // state=1 means undelivered + repoll |= iter->second.pwp->enqueue(iter->second.msg.copy(DMI::WRITE),tick); + } + } + } + // remove signal if one-shot + if( iter->second.flags&EV_ONESHOT ) + signals.erase(iter++); + else + iter++; + } + } + } + + return repoll; +} + + + +string Dispatcher::sdebug ( int detail,const string &,const char *name ) const +{ + string out; + if( detail>=0 ) // basic detail + { + if( name ) + out = string(name) + "/"; + out += address.toString(); + if( detail>3 ) + out += Debug::ssprintf("/%08x",this); + } + if( detail >= 1 || detail == -1 ) // normal detail + { + Debug::appendf(out,"wps:%d",wps.size()); + if( !running ) + Debug::append(out,"stopped"); + } + return out; +} + //## end Dispatcher%3C7B6A3E00A0.declarations +//## begin module%3C7B7F30004B.epilog preserve=yes +//## end module%3C7B7F30004B.epilog diff --git a/CEP/CPA/OCTOPUSSY/src/Dispatcher.h b/CEP/CPA/OCTOPUSSY/src/Dispatcher.h new file mode 100755 index 0000000000000000000000000000000000000000..6da2c1791c2b9fe2c8d2ddab683000d7e761523c --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Dispatcher.h @@ -0,0 +1,455 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7B7F300041.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7B7F300041.cm + +//## begin module%3C7B7F300041.cp preserve=no +//## end module%3C7B7F300041.cp + +//## Module: Dispatcher%3C7B7F300041; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Dispatcher.h + +#ifndef Dispatcher_h +#define Dispatcher_h 1 + +//## begin module%3C7B7F300041.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C7B7F300041.additionalIncludes + +//## begin module%3C7B7F300041.includes preserve=yes +#include <signal.h> +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> +#include <stack> +#include "OCTOPUSSY/Timestamp.h" +#include "OCTOPUSSY/OctopussyConfig.h" +//## end module%3C7B7F300041.includes + +// DataRecord +#include "DMI/DataRecord.h" +// WPInterface +#include "OCTOPUSSY/WPInterface.h" +// OctopussyDebugContext +#include "OCTOPUSSY/OctopussyDebugContext.h" +// Message +#include "OCTOPUSSY/Message.h" + + +//## begin module%3C7B7F300041.declarations preserve=no +//## end module%3C7B7F300041.declarations + +//## begin module%3C7B7F300041.additionalDeclarations preserve=yes +#pragma aid Argv + +// Event flags +const int EV_CONT = 0, // continuous event (keeps firing until removed) + EV_ONESHOT = 1, // one-shot event (clears itself first time it fires) + EV_DISCRETE = 2, // signal: deliver discrete events for each signal + // (default is to not generate a signal if one is already enqueued) + EV_IGNORE = 4, // signal: do not deliver messages, but do + // catch the signal + +// NB: when a WP does an addSignal with EV_IGNORE, it will not receive any +// messages, but the signal will be caught by Dispatcher's handler, and its +// counters (if supplied to addInput) will be incremented + + // for addInput: + EV_FDREAD = 0x100, // report when fd available for reading + EV_FDWRITE = 0x200, // report when fd available for writing + EV_FDEXCEPTION = 0x400, // report when exception on fd + EV_FDALL = 0x700; // mask of all flags for inputs + + +//## end module%3C7B7F300041.additionalDeclarations + + +//## begin Dispatcher%3C7B6A3E00A0.preface preserve=yes +//## end Dispatcher%3C7B6A3E00A0.preface + +//## Class: Dispatcher%3C7B6A3E00A0 +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: 1..1 + + + +//## Uses: <unnamed>%3C7E128D0235;Message { -> } +//## Uses: <unnamed>%3C7E136D0350;WPInterface { -> F} + +class Dispatcher : public OctopussyDebugContext //## Inherits: <unnamed>%3C7FA32C016D +{ + //## begin Dispatcher%3C7B6A3E00A0.initialDeclarations preserve=yes + public: + Debug::Context DebugContext; + ::Debug::Context & getDebugContext() { return DebugContext; }; + + // iterator type (for iterate(), below) + typedef map<WPID,WPRef>::const_iterator WPIter; + //## end Dispatcher%3C7B6A3E00A0.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: Dispatcher%3C7CD444039C + Dispatcher (AtomicID process, AtomicID host, int hz = 100); + + //## Operation: Dispatcher%3CD012B70209 + Dispatcher (int hz = 100); + + //## Destructor (generated) + ~Dispatcher(); + + + //## Other Operations (specified) + //## Operation: attach%3C8CDDFD0361 + const MsgAddress & attach (WPRef &wpref); + + //## Operation: attach%3C7B885A027F + const MsgAddress & attach (WPInterface* wp, int flags); + + //## Operation: detach%3C8CA2BD01B0 + void detach (WPInterface* wp, bool delay = False); + + //## Operation: detach%3C8CDE320231 + void detach (const WPID &id, bool delay = False); + + //## Operation: declareForwarder%3C95C73F022A + // Marks a WP as a "forwarder", i.e., can deliver messages to remote + // hosts. + void declareForwarder (WPInterface *wp); + + //## Operation: start%3C7DFF770140 + void start (); + + //## Operation: stop%3C7E0270027B + void stop (); + + //## Operation: send%3C7B8867015B + // Sends message to specified address. The ref must be writable. + // Read-only copies will be placed into the appropriate queue(s). + int send (MessageRef &mref, const MsgAddress &to); + + //## Operation: poll%3C7B888E01CF + // Polls inputs, checks timeouts, and delivers any queued messages. + // Does not block. + // This method should be called by WPs when busy with long jobs. + void poll (); + + //## Operation: pollLoop%3C8C87AF031F + // Goes into polling loop. Shoud be called after start() to run the + // system. Returns when a SIGINT is received, or after someone has + // called stopPolling(). + void pollLoop (); + + //## Operation: stopPolling%3CA09EB503C1 + void stopPolling (); + + //## Operation: addTimeout%3C7D28C30061 + void addTimeout (WPInterface* pwp, const Timestamp &period, const HIID &id, int flags, int priority); + + //## Operation: addInput%3C7D28E3032E + void addInput (WPInterface* pwp, int fd, int flags, int priority); + + //## Operation: addSignal%3C7DFF4A0344 + void addSignal (WPInterface* pwp, int signum, int flags, volatile int* counter, int priority); + + //## Operation: removeTimeout%3C7D28F202F3 + bool removeTimeout (WPInterface* pwp, const HIID &id); + + //## Operation: removeInput%3C7D2947002F + bool removeInput (WPInterface* pwp, int fd, int flags); + + //## Operation: removeSignal%3C7DFF57025C + bool removeSignal (WPInterface* pwp, int signum); + + //## Operation: numWPs%3C9B05E0027D + int numWPs () const; + + //## Operation: initWPIter%3C98D4530076 + // Returns an iterator pointing to the first WP in the list. Use with + // iterate(). + Dispatcher::WPIter initWPIter (); + + //## Operation: getWPIter%3C98D47B02B9 + // Gets info for WP pointed to by iterator and increments the + // iterator. Returns False when iterator becomes invalid. + bool getWPIter (Dispatcher::WPIter &iter, WPID &wpid, const WPInterface *&pwp); + + //## Operation: addLocalData%3CBEDDD8001A + void addLocalData (const HIID &id, ObjRef ref); + + //## Operation: addLocalData%3CBEE41702F4 + DataField & addLocalData (const HIID &id); + + //## Operation: localData%3CC405480057 + NestableContainer::Hook localData (const HIID &id); + + //## Operation: hasLocalData%3CC00549020D + bool hasLocalData (const HIID &id); + + //## Get and Set Operations for Class Attributes (generated) + + //## Attribute: address%3C7CD390002C + const MsgAddress& getAddress () const; + + //## Attribute: commandLine%3CA031080328 + const vector<string>& getCommandLine () const; + + //## Attribute: tick%3CA1A2B70107 + ulong getTick () const; + + //## Get and Set Operations for Associations (generated) + + //## Association: OCTOPUSSY::<unnamed>%3CBEDD600298 + //## Role: Dispatcher::localData%3CBEDD61016D + const DataRecord& localData () const; + + // Additional Public Declarations + //## begin Dispatcher%3C7B6A3E00A0.public preserve=yes + // pointer to static dispatcher object + static Dispatcher * dispatcher; + + // internal data structures + // EventInfo is a base struct for all system events. + // Contains pointer to WPI, plus a template for the event message + class EventInfo + { + public: WPInterface * pwp; + MessageRef msg; + + EventInfo( WPInterface *pwpi,const HIID &id,int priority ) + : pwp(pwpi), + msg( new Message(AidEvent|id,priority), + DMI::ANON|DMI::WRITE ) + { + msg().setFrom(pwp->dsp()->getAddress()); + msg().setTo(pwp->address()); + }; + }; + class TimeoutInfo : public EventInfo + { + public: Timestamp period,next; + int flags; + HIID id; + TimeoutInfo( WPInterface *pwp,const HIID &id,int priority ) + : EventInfo(pwp,AidTimeout|id,priority) {}; + }; + class InputInfo : public EventInfo + { + public: int fd,flags; + MessageRef last_msg; + InputInfo( WPInterface *pwp,const HIID &id,int priority ) + : EventInfo(pwp,AidInput|id,priority) {}; + }; + class SignalInfo : public EventInfo + { + public: int signum,flags; + volatile int *counter; + SignalInfo( WPInterface *pwp,const HIID &id,int priority ) + : EventInfo(pwp,AidSignal|id,priority) {}; + }; + + // hostId and processId + AtomicID hostId () const { return getAddress().host(); } + AtomicID processId () const { return getAddress().process(); } + + // map of WP classes + map<AtomicID,int> wp_instances; + + // helper function: returns true if id1 is Broadcast or Publish + bool wildcardAddr( AtomicID id1 ) + { return id1 == AidPublish || id1 == AidAny; } + // helper function: returns true if id1 is wilcard or ==id2 + bool matchAddr( AtomicID id1,AtomicID id2 ) + { return wildcardAddr(id1) || id1 == id2; } + + + Declare_sdebug( ); + Declare_debug( ); + //## end Dispatcher%3C7B6A3E00A0.public + protected: + // Additional Protected Declarations + //## begin Dispatcher%3C7B6A3E00A0.protected preserve=yes + // flag: dispatcher is running + bool running; + // flag: repoll required + bool repoll; + // flag: stop the poll loop + static bool stop_polling; + // flag: we are inside the pollLoop() or start() method + bool in_pollLoop,in_start; + // This is the current poll depth (i.e., depth of nested polls) + // when <0, means no poll() calls should be made. + int poll_depth; + + // set of raised signals/all handled signals + static sigset_t raisedSignals,allSignals; + // original sigactions for all signals + static struct sigaction *orig_sigaction[_NSIG]; + // static signal handler + static void signalHandler (int signum,siginfo_t *siginfo,void *); + // heartbeat timer + int heartbeat_hz; + + // timeout list + typedef list<TimeoutInfo> TOIL; + TOIL timeouts; + typedef TOIL::iterator TOILI; + typedef TOIL::const_iterator CTOILI; + Timestamp next_to; // next pending timeout + + // inputs list + typedef list<InputInfo> IIL; + IIL inputs; + typedef IIL::iterator IILI; + typedef IIL::const_iterator CIILI; + typedef struct fdsets { fd_set r,w,x; } FDSets; + FDSets fds_watched,fds_active; + int max_fd,num_active_fds; + Timestamp next_select,inputs_poll_period; + // rebuilds watched fds according to inputs list + // If remove is specified, all entries for the WP are removed from the + // list (remove & rebuild). + void rebuildInputs ( WPInterface *remove = 0 ); + + // signals map + typedef multimap<int,SignalInfo> SigMap; + SigMap signals; + typedef SigMap::iterator SMI; + typedef SigMap::const_iterator CSMI; + typedef SigMap::value_type SMPair; + // rebuilds sigsets and sets up sigactions according to signals map + // If remove is specified, all entries for the WP are removed from the + // list (remove & rebuild).. + void rebuildSignals (WPInterface *remove = 0); + + // checks all signals, timeouts and inputs, sets & returns repoll flag + bool checkEvents (); + + //## end Dispatcher%3C7B6A3E00A0.protected + private: + //## Constructors (generated) + Dispatcher(const Dispatcher &right); + + //## Assignment Operation (generated) + Dispatcher & operator=(const Dispatcher &right); + + + //## Other Operations (specified) + //## Operation: init%3CD014D00180 + void init (); + + // Additional Private Declarations + //## begin Dispatcher%3C7B6A3E00A0.private preserve=yes + //## end Dispatcher%3C7B6A3E00A0.private + + private: //## implementation + // Data Members for Class Attributes + + //## begin Dispatcher::address%3C7CD390002C.attr preserve=no public: MsgAddress {U} + MsgAddress address; + //## end Dispatcher::address%3C7CD390002C.attr + + //## begin Dispatcher::commandLine%3CA031080328.attr preserve=no public: vector<string> {U} + vector<string> commandLine; + //## end Dispatcher::commandLine%3CA031080328.attr + + //## begin Dispatcher::tick%3CA1A2B70107.attr preserve=no public: ulong {U} + ulong tick; + //## end Dispatcher::tick%3CA1A2B70107.attr + + // Data Members for Associations + + //## Association: OCTOPUSSY::<unnamed>%3C7E14150352 + //## Role: Dispatcher::wps%3C7E1416010E + //## begin Dispatcher::wps%3C7E1416010E.role preserve=no protected: WPInterface {1 -> 0..*RHN} + map<WPID,WPRef> wps; + //## end Dispatcher::wps%3C7E1416010E.role + + //## Association: OCTOPUSSY::<unnamed>%3C907A5C03B2 + //## Role: Dispatcher::gateways%3C907A5D01E6 + //## begin Dispatcher::gateways%3C907A5D01E6.role preserve=no protected: WPInterface { -> 0..*RHN} + map<WPID,WPInterface*> gateways; + //## end Dispatcher::gateways%3C907A5D01E6.role + + //## Association: OCTOPUSSY::<unnamed>%3CBEDD600298 + //## begin Dispatcher::localData%3CBEDD61016D.role preserve=no public: DataRecord { -> 1VHgN} + DataRecord localData_; + //## end Dispatcher::localData%3CBEDD61016D.role + + // Additional Implementation Declarations + //## begin Dispatcher%3C7B6A3E00A0.implementation preserve=yes + typedef map<WPID,WPRef>::iterator WPI; + typedef map<WPID,WPRef>::const_iterator CWPI; + typedef map<WPID,WPInterface*>::iterator GWI; + typedef map<WPID,WPInterface*>::const_iterator CGWI; + + // WPs detached with delay=True are placed into this stack, + // which is flushed only at a level-0 repoll + stack<WPRef> detached_wps; + // WPs attached during Dispatcher::start() temporarily go here. + // This is done to avoid upsetting the iterators. + stack<WPRef> attached_wps; + + const OctopussyConfig & config; + //## end Dispatcher%3C7B6A3E00A0.implementation +}; + +//## begin Dispatcher%3C7B6A3E00A0.postscript preserve=yes +//## end Dispatcher%3C7B6A3E00A0.postscript + +// Class Dispatcher + + +//## Other Operations (inline) +inline int Dispatcher::numWPs () const +{ + //## begin Dispatcher::numWPs%3C9B05E0027D.body preserve=yes + return wps.size(); + //## end Dispatcher::numWPs%3C9B05E0027D.body +} + +//## Get and Set Operations for Class Attributes (inline) + +inline const MsgAddress& Dispatcher::getAddress () const +{ + //## begin Dispatcher::getAddress%3C7CD390002C.get preserve=no + return address; + //## end Dispatcher::getAddress%3C7CD390002C.get +} + +inline const vector<string>& Dispatcher::getCommandLine () const +{ + //## begin Dispatcher::getCommandLine%3CA031080328.get preserve=no + return commandLine; + //## end Dispatcher::getCommandLine%3CA031080328.get +} + +inline ulong Dispatcher::getTick () const +{ + //## begin Dispatcher::getTick%3CA1A2B70107.get preserve=no + return tick; + //## end Dispatcher::getTick%3CA1A2B70107.get +} + +//## Get and Set Operations for Associations (inline) + +inline const DataRecord& Dispatcher::localData () const +{ + //## begin Dispatcher::localData%3CBEDD61016D.get preserve=no + return localData_; + //## end Dispatcher::localData%3CBEDD61016D.get +} + +//## begin module%3C7B7F300041.epilog preserve=yes +//## end module%3C7B7F300041.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/GWClientWP.cc b/CEP/CPA/OCTOPUSSY/src/GWClientWP.cc new file mode 100755 index 0000000000000000000000000000000000000000..baa7a75f553a0b4e6e789303c5352bc5a4f37750 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/GWClientWP.cc @@ -0,0 +1,514 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C95AADB0170.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C95AADB0170.cm + +//## begin module%3C95AADB0170.cp preserve=no +//## end module%3C95AADB0170.cp + +//## Module: GWClientWP%3C95AADB0170; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\GWClientWP.cc + +//## begin module%3C95AADB0170.additionalIncludes preserve=no +//## end module%3C95AADB0170.additionalIncludes + +//## begin module%3C95AADB0170.includes preserve=yes +#include "Gateways.h" +#include "GWServerWP.h" +//## end module%3C95AADB0170.includes + +// GWClientWP +#include "OCTOPUSSY/GWClientWP.h" +//## begin module%3C95AADB0170.declarations preserve=no +//## end module%3C95AADB0170.declarations + +//## begin module%3C95AADB0170.additionalDeclarations preserve=yes +const Timeval ReconnectTimeout(.2), + ReopenTimeout(2.0), +// how long to try connect() (if operation in progress is returned) + FailConnectTimeout(10.0), +// how long to try connects() before giving up on a transient connection + GiveUpTimeout(30.0); + +//## end module%3C95AADB0170.additionalDeclarations + + +// Class GWClientWP + +GWClientWP::GWClientWP (const string &host, int port, int type) + //## begin GWClientWP::GWClientWP%3CD0167B021B.hasinit preserve=no + //## end GWClientWP::GWClientWP%3CD0167B021B.hasinit + //## begin GWClientWP::GWClientWP%3CD0167B021B.initialization preserve=yes + : WorkProcess(AidGWClientWP), + peerref(new DataRecord,DMI::ANONWR), + peerlist(dynamic_cast<DataRecord&>(peerref.dewr())) + //## end GWClientWP::GWClientWP%3CD0167B021B.initialization +{ + //## begin GWClientWP::GWClientWP%3CD0167B021B.body preserve=yes + // add default connection, if specified + if( host.length() ) + { + FailWhen(!port,"both host and port must be specified"); + addConnection(host,port,type); + } + // add connections from config + string peers; + if( config.get("gwpeer",peers) ) + { + while( peers.length() ) + { + // split into "host1:port1,host2:port2,", etc. + string peer; + size_t pos = peers.find_first_of(','); + if( pos != string::npos ) + { + peer = peers.substr(0,pos); + peers = peers.substr(pos+1); + } + else + { + peer = peers; + peers = ""; + } + pos = peer.find_first_of(':'); + FailWhen(pos == string::npos || !pos,"malformed 'gwpeer' specification"); + string host = peer.substr(0,pos); + int port = atoi(peer.substr(pos+1).c_str()); + int type = ( host[0] == '=' || host.find_first_of('/') != string::npos ) + ? Socket::UNIX : Socket::TCP; + addConnection(host,port,type); + } + } + + // get the local hostname + char hname[1024]; + FailWhen(gethostname(hname,sizeof(hname))<0,"gethostname(): "+string(strerror(errno))); + hostname = hname; + setState(STOPPED); + //## end GWClientWP::GWClientWP%3CD0167B021B.body +} + + +GWClientWP::~GWClientWP() +{ + //## begin GWClientWP::~GWClientWP%3C95A941002E_dest.body preserve=yes + for( CCLI iter = conns.begin(); iter != conns.end(); iter++ ) + if( iter->sock ) + delete iter->sock; + //## end GWClientWP::~GWClientWP%3C95A941002E_dest.body +} + + + +//## Other Operations (implementation) +void GWClientWP::init () +{ + //## begin GWClientWP::init%3CA1C0C300FA.body preserve=yes + // add our peerlist to local data + dsp()->addLocalData(GWPeerList,peerref.copy(DMI::WRITE)); + if( !dsp()->hasLocalData(GWNetworkServer) ) + dsp()->localData(GWNetworkServer) = -1; + if( !dsp()->hasLocalData(GWLocalServer) ) + dsp()->localData(GWLocalServer) = ""; + // messages from server gateway tell us when it fails to bind + // to a port/when it binds/when it gives up + subscribe(MsgGWServer|AidWildcard,Message::LOCAL); + // subscribe to server advertisements + subscribe(MsgGWServerOpenNetwork,Message::GLOBAL); + subscribe(MsgGWServerOpenLocal,Message::HOST); + // Bye messages from child gateways tell us when they have closed + // (and thus need to be reopened) + subscribe(MsgBye|AidGatewayWP|AidWildcard,Message::LOCAL); + // Remote messages for remote node management + subscribe(MsgGWRemote|AidWildcard,Message::LOCAL); + subscribe(MsgGWRemoteUp|AidWildcard,Message::GLOBAL); + //## end GWClientWP::init%3CA1C0C300FA.body +} + +bool GWClientWP::start () +{ + //## begin GWClientWP::start%3C95A941008B.body preserve=yes + activate(); + return WorkProcess::start(); + //## end GWClientWP::start%3C95A941008B.body +} + +void GWClientWP::stop () +{ + //## begin GWClientWP::stop%3C95A9410092.body preserve=yes + setState(STOPPED); + for( CLI iter = conns.begin(); iter != conns.end(); iter++ ) + { + if( iter->sock ) + delete iter->sock; + iter->sock = 0; + iter->state = STOPPED; + } + //## end GWClientWP::stop%3C95A9410092.body +} + +int GWClientWP::timeout (const HIID &id) +{ + //## begin GWClientWP::timeout%3C95A9410093.body preserve=yes + bool connecting = False; + Timestamp::now(&now); + // go thru connection list and figure out what to do + for( CLI iter = conns.begin(); iter != conns.end(); iter++ ) + { + switch( iter->state ) + { + case CONNECTED: // do nothing + break; + + case CONNECTING: // connecting? + if( now >= iter->fail ) // check for timeout + { + lprintf(1,"connect(%s:%d) timeout; will retry later",iter->host.c_str(),iter->port); + delete iter->sock; iter->sock = 0; + iter->state = WAITING; + iter->retry = now + ReopenTimeout; + break; + } + + case STOPPED: + case WAITING: // not connecting - is it time for a retry? + if( now >= iter->retry ) + tryConnect(*iter); + break; + + default: + lprintf(1,"error: unexpected state %d for %s:%d\n",iter->state, + iter->host.c_str(),iter->port); + } + if( iter->state == CONNECTING ) + connecting = True; + } + // if reconnecting timeout (i.e. short one) is set, and no-one + // seems to be connecting, then cancel it + if( id == AidReconnect && !connecting ) + { + reconnect_timeout_set = False; + return Message::CANCEL; + } + if( connecting && !reconnect_timeout_set ) + { + addTimeout(ReconnectTimeout,AidReconnect); + reconnect_timeout_set = True; + } + + return Message::ACCEPT; + //## end GWClientWP::timeout%3C95A9410093.body +} + +int GWClientWP::receive (MessageRef& mref) +{ + //## begin GWClientWP::receive%3C95A9410095.body preserve=yes + const Message &msg = mref.deref(); + const HIID &id = msg.id(); + if( id == MsgGWServerBindError ) + { + // server has failed to bind to a port -- assume a local peer has already + // bound to it, so add it to our connection list + int type = msg[AidType]; + if( type == Socket::UNIX ) + { + string host = msg[AidHost]; + int port = msg[AidPort]; + Connection &cx = addConnection(host,port,type); + lprintf(2,LogNormal,"adding %s:%d to connection list",host.c_str(),port); + if( state() != STOPPED ) + tryConnect(cx); + } + } + // a non-local server advertisement: see if we need to establish + // a connection to it + else if( id.matches(MsgGWServerOpen|AidWildcard) && !isLocal(msg) ) + { + // ignore local server advertisements from non-local hosts + if( id == MsgGWServerOpenLocal && msg.from().host() != address().host() ) + return Message::ACCEPT; + // ignore network server advertisements from local host + if( id == MsgGWServerOpenNetwork && msg.from().host() == address().host() ) + return Message::ACCEPT; + HIID peerid = msg.from().peerid(); + if( peerlist[peerid].exists() ) + { + lprintf(3,"peer-adv %s: already connected (%s:%d %s), ignoring", + peerid.toString().c_str(), + peerlist[peerid][AidHost].as_string().c_str(), + peerlist[peerid][AidPort].as_int(), + peerlist[peerid][AidTimestamp].as_Timestamp().toString("%T").c_str()); + } + else + { + // initiate a connection only if (a) we don't have a server ourselves, + // or (b) our peerid is < remote + // This ensures that only one peer of any given pair actually makes the + // connection. + string host = msg[AidHost]; + int port = msg[AidPort]; + int type = msg[AidType]; + // advertisement for a local connection? + if( type == Socket::UNIX ) + { + if( !dsp()->localData(GWLocalServer).as_string().length() ) + lprintf(2,"peer-adv %s@%s:%d: no unix server here, initiating connection",peerid.toString().c_str(),host.c_str(),port); + else if( address().peerid() < peerid ) + lprintf(2,"peer-adv %s@%s:%d: higher rank, initiating connection",peerid.toString().c_str(),host.c_str(),port); + else + { + lprintf(2,"peer-adv %s@%s:%d: lower rank, ignoring and waiting for connection",peerid.toString().c_str(),host.c_str(),port); + return Message::ACCEPT; + } + } + else // network connection + { + if( !dsp()->localData(GWNetworkServer).as_int() < 0 ) + lprintf(2,"peer-adv %s@%s:%d: no network server here, initiating connection",peerid.toString().c_str(),host.c_str(),port); + else if( address().peerid() < peerid ) + lprintf(2,"peer-adv %s@%s:%d: higher rank, initiating connection",peerid.toString().c_str(),host.c_str(),port); + else + { + lprintf(2,"peer-adv %s@%s:%d: lower rank, ignoring and waiting for connection",peerid.toString().c_str(),host.c_str(),port); + return Message::ACCEPT; + } + if( host == hostname ) + host = "localhost"; + } + // create the connection + Connection &cx = addConnection(host,port,type); + cx.give_up = Timestamp::now() + GiveUpTimeout; + if( state() != STOPPED ) + tryConnect(cx); + } + } + else if( id.prefixedBy(MsgGWRemoteDuplicate) ) + { + // message from child gateway advises us of a duplicate connection -- better + // remove this from the connection list + if( msg[AidHost].exists() ) + { + const string &host = msg[AidHost]; + int port = msg[AidPort]; + if( removeConnection(host,port) ) + lprintf(2,LogNormal,"removed duplicate connection %s:%d",host.c_str(),port); +// else +// lprintf(2,LogWarning,"%s:%d not known, ignoring [%s]", +// host.c_str(),port,msg.sdebug(1).c_str()); + } + } + // bye message from child? Reopen its gateway then + // (unless the connection has been removed by MsgGWRemoteDuplicate, above) + else if( id.prefixedBy(MsgBye|AidGatewayWP) ) + { + Connection *cx = find(msg.from()); + if( cx ) + { + lprintf(2,"caught Bye from child gateway for %s:%d, waking up\n", + cx->host.c_str(),cx->port); + if( cx->state == CONNECTED ) // just to make sure it's not a stray message + { + if( cx->give_up ) + cx->give_up = Timestamp::now() + GiveUpTimeout; + cx->state = WAITING; + tryConnect(*cx); + } + } + } + return Message::ACCEPT; + //## end GWClientWP::receive%3C95A9410095.body +} + +// Additional Declarations + //## begin GWClientWP%3C95A941002E.declarations preserve=yes +GWClientWP::Connection & GWClientWP::addConnection (const string &host,int port,int type) +{ + for( CLI iter = conns.begin(); iter != conns.end(); iter++ ) + if( iter->host == host && iter->port == port ) + return *iter; + Connection cx; + cx.host = host; + cx.port = port; + cx.type = type; + cx.sock = 0; + cx.state = STOPPED; + cx.give_up = Timestamp(0,0); + cx.reported_failure = False; + conns.push_back(cx); + return conns.back(); +} + +bool GWClientWP::removeConnection (const string &host,int port) +{ + bool localhost = (host == "localhost"); + bool res = False; + for( CLI iter = conns.begin(); iter != conns.end(); ) + if( iter->port == port && + ( iter->host == host || ( localhost && iter->host == "localhost" ) ) ) + { + conns.erase(iter++); + res = True; + } + else + iter++; + return res; +} + +GWClientWP::Connection * GWClientWP::find (const string &host, const string &port) +{ + for( CLI iter = conns.begin(); iter != conns.end(); iter++ ) + if( iter->host == host && iter->port == port ) + return &(*iter); + return 0; +} + +GWClientWP::Connection * GWClientWP::find (const MsgAddress &gw) +{ + for( CLI iter = conns.begin(); iter != conns.end(); iter++ ) + if( iter->gw == gw ) + return &(*iter); + return 0; +} + + + +void GWClientWP::activate () +{ + Timestamp::now(&now); + setState(CONNECTING); + // initiate connection on every socket + for( CLI iter = conns.begin(); iter != conns.end(); iter++ ) + tryConnect(*iter); + // add a re-open timeout + addTimeout(ReopenTimeout,AidReopen); +} + +void GWClientWP::tryConnect (Connection &cx) +{ + if( cx.state == CONNECTED ) // ignore if connected + return; + if( cx.state != CONNECTING ) // try to reconnect completely + { + if( cx.sock ) + delete cx.sock; + lprintf(4,"creating client socket for %s:%d\n", + cx.host.c_str(),cx.port); + cx.sock = new Socket("cx.sock/"+wpname(),cx.host,num2str(cx.port),cx.type,-1); + cx.state = CONNECTING; + cx.fail = now + FailConnectTimeout; + // fall thru to connection attempt, below + } + if( !cx.sock ) // sanity check + return; + // [re]try connection attempt + int res = cx.sock->connect(0); + dprintf(3)("connect(%s:%d): %d (%s)\n",cx.host.c_str(),cx.port, + res,cx.sock->errstr().c_str()); + if( res > 0 ) // connection established + { + lprintf(1,"connected to %s:%d, spawning child gateway\n", + cx.host.c_str(),cx.port); + cx.state = CONNECTED; + // spawn a new child gateway, subscribe to its Bye message + cx.gw = attachWP( new GatewayWP(cx.sock),DMI::ANON ); + cx.sock = 0; // socket is taken over by child + cx.reported_failure = False; + } + else if( !res ) // in progress + { + dprintf(3)("connect still in progress\n"); + if( !reconnect_timeout_set ) + { + addTimeout(ReconnectTimeout,AidReconnect); + reconnect_timeout_set = True; + } + } + else // else it is a fatal error, close and retry + { + if( cx.give_up && now > cx.give_up ) + { + lprintf(2,"connect(%s:%d) error: %s; giving up", + cx.host.c_str(),cx.port,cx.sock->errstr().c_str()); + delete cx.sock; + removeConnection(cx.host,cx.port); + } + else + { + lprintf(cx.reported_failure?4:2,"connect(%s:%d) error: %s; will keep trying", + cx.host.c_str(),cx.port,cx.sock->errstr().c_str()); + cx.reported_failure = True; + delete cx.sock; cx.sock = 0; + cx.state = WAITING; + cx.retry = now + ReopenTimeout; + } + } +} + //## end GWClientWP%3C95A941002E.declarations +//## begin module%3C95AADB0170.epilog preserve=yes +void initGateways (Dispatcher &dsp) +{ + dsp.attach(new GWServerWP(-1),DMI::ANON); + dsp.attach(new GWServerWP("",0),DMI::ANON); + dsp.attach(new GWClientWP,DMI::ANON); +} + +//## end module%3C95AADB0170.epilog + + +// Detached code regions: +#if 0 +//## begin GWClientWP::GWClientWP%3C95A9410081.initialization preserve=yes + : WorkProcess(AidGWClientWP), + peerref(new DataRecord,DMI::ANONWR), + peerlist(dynamic_cast<DataRecord&>(peerref.dewr())) +//## end GWClientWP::GWClientWP%3C95A9410081.initialization + +//## begin GWClientWP::GWClientWP%3C95A9410081.body preserve=yes + // add default connection, if specified + if( host.length() ) + { + FailWhen(!port,"both host and port must be specified"); + addConnection(host,port,type); + } + // add connections from config + string peers; + if( config.get("gwpeer",peers) ) + { + while( peers.length() ) + { + // split into "host1:port1,host2:port2,", etc. + string peer; + size_t pos = peers.find_first_of(','); + if( pos != string::npos ) + { + peer = peers.substr(0,pos); + peers = peers.substr(pos+1); + } + else + { + peer = peers; + peers = ""; + } + pos = peer.find_first_of(':'); + FailWhen(pos == string::npos || !pos,"malformed 'gwpeer' specification"); + string host = peer.substr(0,pos); + int port = atoi(peer.substr(pos+1).c_str()); + int type = ( host[0] == '=' || host.find_first_of('/') != string::npos ) + ? Socket::UNIX : Socket::TCP; + addConnection(host,port,type); + } + } + + // get the local hostname + char hname[1024]; + FailWhen(gethostname(hname,sizeof(hname))<0,"gethostname(): "+string(strerror(errno))); + hostname = hname; + setState(STOPPED); +//## end GWClientWP::GWClientWP%3C95A9410081.body + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/GWClientWP.h b/CEP/CPA/OCTOPUSSY/src/GWClientWP.h new file mode 100755 index 0000000000000000000000000000000000000000..fa944b1de386abf0f66321032b7823470fd8a338 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/GWClientWP.h @@ -0,0 +1,165 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C95AADB016E.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C95AADB016E.cm + +//## begin module%3C95AADB016E.cp preserve=no +//## end module%3C95AADB016E.cp + +//## Module: GWClientWP%3C95AADB016E; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\GWClientWP.h + +#ifndef GWClientWP_h +#define GWClientWP_h 1 + +//## begin module%3C95AADB016E.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C95AADB016E.additionalIncludes + +//## begin module%3C95AADB016E.includes preserve=yes +#include <list> +//## end module%3C95AADB016E.includes + +// Socket +#include "OCTOPUSSY/Net/Socket.h" +// GatewayWP +#include "OCTOPUSSY/GatewayWP.h" +// WorkProcess +#include "OCTOPUSSY/WorkProcess.h" +//## begin module%3C95AADB016E.declarations preserve=no +//## end module%3C95AADB016E.declarations + +//## begin module%3C95AADB016E.additionalDeclarations preserve=yes +#pragma aid Reconnect FailConnect Reopen Server List Hosts Ports +//## end module%3C95AADB016E.additionalDeclarations + + +//## begin GWClientWP%3C95A941002E.preface preserve=yes +//## end GWClientWP%3C95A941002E.preface + +//## Class: GWClientWP%3C95A941002E +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +//## Uses: <unnamed>%3C95AA83029E;GatewayWP { -> } + +class GWClientWP : public WorkProcess //## Inherits: <unnamed>%3C95A941009C +{ + //## begin GWClientWP%3C95A941002E.initialDeclarations preserve=yes + public: + typedef struct { string host; + int port; + int type; + Socket *sock; + int state; + Timestamp retry,fail,give_up; + bool reported_failure; + // When we spawn a child gateway, we watch for its bye message + // to know when to start connecting again. This holds its address. + MsgAddress gw; + } Connection; + //## end GWClientWP%3C95A941002E.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: GWClientWP%3CD0167B021B + GWClientWP (const string &host = "", int port = 0, int type = Socket::TCP); + + //## Destructor (generated) + ~GWClientWP(); + + + //## Other Operations (specified) + //## Operation: init%3CA1C0C300FA + virtual void init (); + + //## Operation: start%3C95A941008B + bool start (); + + //## Operation: stop%3C95A9410092 + void stop (); + + //## Operation: timeout%3C95A9410093 + int timeout (const HIID &id); + + //## Operation: receive%3C95A9410095 + int receive (MessageRef& mref); + + // Additional Public Declarations + //## begin GWClientWP%3C95A941002E.public preserve=yes + typedef enum { STOPPED=0,WAITING=1,CONNECTING=2,CONNECTED=3 } States; + //## end GWClientWP%3C95A941002E.public + protected: + // Additional Protected Declarations + //## begin GWClientWP%3C95A941002E.protected preserve=yes + // maintain connection list + Connection & addConnection (const string &host,int port,int type); + bool removeConnection (const string &host,int port); + GWClientWP::Connection * find (const string &host, const string &port); + GWClientWP::Connection * find (const MsgAddress &gw); + + // begins connecting + void activate (); + // tries to open and connect the socket + void tryConnect ( Connection &cx ); + + Timestamp now; + bool reconnect_timeout_set; + + ObjRef peerref; + DataRecord & peerlist; + //## end GWClientWP%3C95A941002E.protected + private: + //## Constructors (generated) + GWClientWP(const GWClientWP &right); + + //## Assignment Operation (generated) + GWClientWP & operator=(const GWClientWP &right); + + // Additional Private Declarations + //## begin GWClientWP%3C95A941002E.private preserve=yes + //## end GWClientWP%3C95A941002E.private + + private: //## implementation + // Data Members for Class Attributes + + //## Attribute: hostname%3CC951FA0127 + //## begin GWClientWP::hostname%3CC951FA0127.attr preserve=no private: string {U} + string hostname; + //## end GWClientWP::hostname%3CC951FA0127.attr + + // Data Members for Associations + + //## Association: OCTOPUSSY::<unnamed>%3C95A941009D + //## Role: GWClientWP::conns%3C95A941009E + //## begin GWClientWP::conns%3C95A941009E.role preserve=no private: Socket { -> 0..*RHgN} + list<Connection> conns; + //## end GWClientWP::conns%3C95A941009E.role + + // Additional Implementation Declarations + //## begin GWClientWP%3C95A941002E.implementation preserve=yes + typedef list<Connection>::iterator CLI; + typedef list<Connection>::const_iterator CCLI; + //## end GWClientWP%3C95A941002E.implementation +}; + +//## begin GWClientWP%3C95A941002E.postscript preserve=yes +//## end GWClientWP%3C95A941002E.postscript + +// Class GWClientWP + +//## begin module%3C95AADB016E.epilog preserve=yes +//## end module%3C95AADB016E.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/GWServerWP.cc b/CEP/CPA/OCTOPUSSY/src/GWServerWP.cc new file mode 100755 index 0000000000000000000000000000000000000000..3acd7653383f5483b77e727e1ac279b538c712db --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/GWServerWP.cc @@ -0,0 +1,295 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C95AADB010A.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C95AADB010A.cm + +//## begin module%3C95AADB010A.cp preserve=no +//## end module%3C95AADB010A.cp + +//## Module: GWServerWP%3C95AADB010A; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\GWServerWP.cc + +//## begin module%3C95AADB010A.additionalIncludes preserve=no +//## end module%3C95AADB010A.additionalIncludes + +//## begin module%3C95AADB010A.includes preserve=yes +#include "Gateways.h" +//## end module%3C95AADB010A.includes + +// GWServerWP +#include "OCTOPUSSY/GWServerWP.h" +//## begin module%3C95AADB010A.declarations preserve=no +//## end module%3C95AADB010A.declarations + +//## begin module%3C95AADB010A.additionalDeclarations preserve=yes +// timeout value for a retry of bind, in seconds +const Timeval Timeout_Retry(10.0), +// re-advertise timeout, in seconds + Timeout_Advertise(10.0); +// max retries +const int MaxOpenRetries = 10; + +//## end module%3C95AADB010A.additionalDeclarations + + +// Class GWServerWP + +GWServerWP::GWServerWP (int port1) + //## begin GWServerWP::GWServerWP%3C8F95710177.hasinit preserve=no + //## end GWServerWP::GWServerWP%3C8F95710177.hasinit + //## begin GWServerWP::GWServerWP%3C8F95710177.initialization preserve=yes + : WorkProcess(AidGWServerWP),port(port1),sock(0),type(Socket::TCP) + //## end GWServerWP::GWServerWP%3C8F95710177.initialization +{ + //## begin GWServerWP::GWServerWP%3C8F95710177.body preserve=yes + // get port from config if not specified explicitly + if( port<0 ) + config.get("gwport",port,4808); + // get the local hostname + char hname[1024]; + FailWhen(gethostname(hname,sizeof(hname))<0,"gethostname(): "+string(strerror(errno))); + hostname = hname; + //## end GWServerWP::GWServerWP%3C8F95710177.body +} + +GWServerWP::GWServerWP (const string &path, int port1) + //## begin GWServerWP::GWServerWP%3CC95151026E.hasinit preserve=no + //## end GWServerWP::GWServerWP%3CC95151026E.hasinit + //## begin GWServerWP::GWServerWP%3CC95151026E.initialization preserve=yes + : WorkProcess(AidGWServerWP),port(port1),sock(0),type(Socket::UNIX) + //## end GWServerWP::GWServerWP%3CC95151026E.initialization +{ + //## begin GWServerWP::GWServerWP%3CC95151026E.body preserve=yes + // get path from config, if not specified explicitly + hostname = path; + if( !hostname.length() ) + { + config.get("gwpath",hostname,"=octopussy-%U"); + // check if port number is part of pathname -- + // find last segment after ":", and check that it is all digits + size_t pos0 = hostname.find_last_of(':'); + if( pos0 != string::npos ) + { + size_t pos = pos0+1; + for( ; pos < hostname.length(); pos++ ) + if( !isdigit(hostname[pos]) ) + break; + if( pos >= hostname.length() ) + { + port = atoi(hostname.substr(pos0+1).c_str()); + hostname = hostname.substr(0,pos0); + } + } + // if hostname contains a "@U" string, replace with uid + string uid = Debug::ssprintf("%d",(int)getuid()); + while( (pos0 = hostname.find_first_of("%U")) != string::npos ) + hostname = hostname.substr(0,pos0) + uid + hostname.substr(pos0+2); + } + //## end GWServerWP::GWServerWP%3CC95151026E.body +} + + +GWServerWP::~GWServerWP() +{ + //## begin GWServerWP::~GWServerWP%3C8F942502BA_dest.body preserve=yes + if( sock ) + delete sock; + //## end GWServerWP::~GWServerWP%3C8F942502BA_dest.body +} + + + +//## Other Operations (implementation) +void GWServerWP::init () +{ + //## begin GWServerWP::init%3CC951680113.body preserve=yes + subscribe(MsgGWRemoteUp|AidWildcard,Message::GLOBAL); + // add local server port as -1 to indicate no active server + if( type == Socket::TCP ) + { + if( !dsp()->hasLocalData(GWNetworkServer) ) + dsp()->localData(GWNetworkServer) = -1; + } + else + { + if( !dsp()->hasLocalData(GWLocalServer) ) + dsp()->localData(GWLocalServer) = ""; + } + //## end GWServerWP::init%3CC951680113.body +} + +bool GWServerWP::start () +{ + //## begin GWServerWP::start%3C90BE4A029B.body preserve=yes + WorkProcess::start(); + open_retries = 0; + tryOpen(); + return False; + //## end GWServerWP::start%3C90BE4A029B.body +} + +void GWServerWP::stop () +{ + //## begin GWServerWP::stop%3C90BE880037.body preserve=yes + WorkProcess::stop(); + if( sock ) + delete sock; + sock = 0; + //## end GWServerWP::stop%3C90BE880037.body +} + +int GWServerWP::timeout (const HIID &) +{ + //## begin GWServerWP::timeout%3C90BE8E000E.body preserve=yes + if( !sock || !sock->ok() ) + tryOpen(); +#if ADVERTISE_SERVERS + else + advertiseServer(); +#endif + return Message::ACCEPT; + //## end GWServerWP::timeout%3C90BE8E000E.body +} + +int GWServerWP::input (int , int ) +{ + //## begin GWServerWP::input%3C95B4DC031C.body preserve=yes + // This is called when an incoming connection is requested + // (since we only have one active input, we don't need no arguments) + if( !sock ) // sanity check + return Message::CANCEL; + // do an accept on the socket + Socket *newsock = sock->accept(); + if( newsock ) // success? Launch a Gateway WP to manage it + { + lprintf(1,"accepted new connection, launching gateway\n"); + attachWP(new GatewayWP(newsock),DMI::ANON); + return Message::ACCEPT; + } + else + { + lprintf(1,"error: accept(): %s.\nClosing and retrying\n",sock->errstr().c_str()); + // just to be anal, close the socket and retry binding it + if( type == Socket::TCP ) + dsp()->localData(GWNetworkServer)[0] = -1; + else + dsp()->localData(GWLocalServer)[0] = ""; + open_retries = 0; + tryOpen(); + return Message::CANCEL; + } + //## end GWServerWP::input%3C95B4DC031C.body +} + +int GWServerWP::receive (MessageRef &mref) +{ + //## begin GWServerWP::receive%3CC951890246.body preserve=yes + if( mref->id().matches(MsgGWRemoteUp|AidWildcard) && sock && sock->ok() ) + advertiseServer(); + return Message::ACCEPT; + //## end GWServerWP::receive%3CC951890246.body +} + +// Additional Declarations + //## begin GWServerWP%3C8F942502BA.declarations preserve=yes + +void GWServerWP::advertiseServer () +{ + if( !advertisement.valid() ) + { + Message *msg = new Message( type == Socket::UNIX + ? MsgGWServerOpenLocal + : MsgGWServerOpenNetwork ); + advertisement <<= msg; + (*msg)[AidHost] = hostname; + (*msg)[AidPort] = port; + (*msg)[AidType] = type; + } + lprintf(4,"advertising server on %s:%d",hostname.c_str(),port); + publish(advertisement.copy(), + type == Socket::UNIX ? Message::HOST : Message::GLOBAL ); +} + +void GWServerWP::tryOpen () +{ + // Try to start a server socket + for( ;; ) + { + if( sock ) + delete sock; + string sockport = num2str(port); + if( type == Socket::UNIX ) + sockport = hostname + ":" + sockport; + sock = new Socket("sock/"+wpname(),sockport,type,10); + if( !sock->ok() ) + { + if( sock->errcode() == Socket::BIND ) + { + // if bind error, assume another process already has it open, + // so launch a GWClientWP to attach to it, and commit harakiri + lprintf(1,"server socket %s:%d already bound\n", + hostname.c_str(),port); + MessageRef mref(new Message(MsgGWServerBindError),DMI::ANON|DMI::WRITE); + Message &msg = mref; + msg[AidHost] = hostname; + msg[AidPort] = port; + msg[AidType] = type; + publish(mref,Message::LOCAL); + // try the next port + port++; + continue; + } + else // some other error + { + string err = sock->errstr(); + lprintf(1,LogError,"fatal error (%s) on server socket %s:%d\n", + err.c_str(),hostname.c_str(),port); + delete sock; sock=0; + if( open_retries++ > MaxOpenRetries ) + { + lprintf(1,LogError,"fatal error (%s) on server socket %s:%d, giving up\n", + err.c_str(),hostname.c_str(),port); + MessageRef mref(new Message(MsgGWServerFatalError),DMI::ANON|DMI::WRITE); + Message &msg = mref; + msg[AidHost] = hostname; + msg[AidPort] = port; + msg[AidType] = type; + msg[AidError] = sock->errstr(); + publish(mref,Message::LOCAL); + detachMyself(); + } + else // retry later - schedule a timeout + { + lprintf(1,LogError,"fatal error (%s) on server socket %s:%d, will retry later\n", + err.c_str(),hostname.c_str(),port); + addTimeout(Timeout_Retry,0,EV_ONESHOT); + } + return; + } + } + // since we got here, the socket is OK + // shout about it + lprintf(1,"opened server socket %s:%d\n",hostname.c_str(),port); + advertiseServer(); + if( type == Socket::TCP ) + dsp()->localData(GWNetworkServer)[0] = port; + else + dsp()->localData(GWLocalServer)[0] = hostname + ":" + port; + // add an input on the socket + addInput(sock->getSid(),EV_FDREAD); +#if ADVERTISE_SERVERS + // add a continuous re-advertise timeout so that open servers + // are re-broadcast across the system (in case someone loses a connection) + addTimeout(Timeout_Advertise,0,EV_CONT); +#endif + return; + } +} + //## end GWServerWP%3C8F942502BA.declarations +//## begin module%3C95AADB010A.epilog preserve=yes +//## end module%3C95AADB010A.epilog diff --git a/CEP/CPA/OCTOPUSSY/src/GWServerWP.h b/CEP/CPA/OCTOPUSSY/src/GWServerWP.h new file mode 100755 index 0000000000000000000000000000000000000000..50971906bfc33a614c1ddd3b91525b1d558aafed --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/GWServerWP.h @@ -0,0 +1,151 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C95AADB0101.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C95AADB0101.cm + +//## begin module%3C95AADB0101.cp preserve=no +//## end module%3C95AADB0101.cp + +//## Module: GWServerWP%3C95AADB0101; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\GWServerWP.h + +#ifndef GWServerWP_h +#define GWServerWP_h 1 + +//## begin module%3C95AADB0101.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C95AADB0101.additionalIncludes + +//## begin module%3C95AADB0101.includes preserve=yes +//## end module%3C95AADB0101.includes + +// Socket +#include "OCTOPUSSY/Net/Socket.h" +// GatewayWP +#include "OCTOPUSSY/GatewayWP.h" +// WorkProcess +#include "OCTOPUSSY/WorkProcess.h" +//## begin module%3C95AADB0101.declarations preserve=no +//## end module%3C95AADB0101.declarations + +//## begin module%3C95AADB0101.additionalDeclarations preserve=yes +#pragma aid Gateway GWServerWP GWClientWP GatewayWP +//## end module%3C95AADB0101.additionalDeclarations + + +//## begin GWServerWP%3C8F942502BA.preface preserve=yes +//## end GWServerWP%3C8F942502BA.preface + +//## Class: GWServerWP%3C8F942502BA +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +//## Uses: <unnamed>%3C90BEFA02E4;GatewayWP { -> } + +class GWServerWP : public WorkProcess //## Inherits: <unnamed>%3C8F943E01B2 +{ + //## begin GWServerWP%3C8F942502BA.initialDeclarations preserve=yes + //## end GWServerWP%3C8F942502BA.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: GWServerWP%3C8F95710177 + GWServerWP (int port1 = -1); + + //## Operation: GWServerWP%3CC95151026E + GWServerWP (const string &path = "", int port1 = -1); + + //## Destructor (generated) + ~GWServerWP(); + + + //## Other Operations (specified) + //## Operation: init%3CC951680113 + virtual void init (); + + //## Operation: start%3C90BE4A029B + virtual bool start (); + + //## Operation: stop%3C90BE880037 + virtual void stop (); + + //## Operation: timeout%3C90BE8E000E + virtual int timeout (const HIID &); + + //## Operation: input%3C95B4DC031C + virtual int input (int , int ); + + //## Operation: receive%3CC951890246 + virtual int receive (MessageRef &mref); + + // Additional Public Declarations + //## begin GWServerWP%3C8F942502BA.public preserve=yes + void advertiseServer(); + + //## end GWServerWP%3C8F942502BA.public + protected: + // Additional Protected Declarations + //## begin GWServerWP%3C8F942502BA.protected preserve=yes + // tries to open server socket + void tryOpen (); + //## end GWServerWP%3C8F942502BA.protected + private: + //## Constructors (generated) + GWServerWP(const GWServerWP &right); + + //## Assignment Operation (generated) + GWServerWP & operator=(const GWServerWP &right); + + // Additional Private Declarations + //## begin GWServerWP%3C8F942502BA.private preserve=yes + //## end GWServerWP%3C8F942502BA.private + + private: //## implementation + // Data Members for Class Attributes + + //## Attribute: port%3C90BE3503C7 + //## begin GWServerWP::port%3C90BE3503C7.attr preserve=no public: int {U} + int port; + //## end GWServerWP::port%3C90BE3503C7.attr + + //## Attribute: hostname%3CC951EA0214 + //## begin GWServerWP::hostname%3CC951EA0214.attr preserve=no private: string {U} + string hostname; + //## end GWServerWP::hostname%3CC951EA0214.attr + + // Data Members for Associations + + //## Association: OCTOPUSSY::<unnamed>%3C922571000B + //## Role: GWServerWP::sock%3C92257101CE + //## begin GWServerWP::sock%3C92257101CE.role preserve=no private: Socket { -> 0..1RHgN} + Socket *sock; + //## end GWServerWP::sock%3C92257101CE.role + + // Additional Implementation Declarations + //## begin GWServerWP%3C8F942502BA.implementation preserve=yes + int type; // Socket::TCP or Socket::UNIX + MessageRef advertisement; + int open_retries; + //## end GWServerWP%3C8F942502BA.implementation +}; + +//## begin GWServerWP%3C8F942502BA.postscript preserve=yes +//## end GWServerWP%3C8F942502BA.postscript + +// Class GWServerWP + +//## begin module%3C95AADB0101.epilog preserve=yes +//## end module%3C95AADB0101.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/GatewayWP.cc b/CEP/CPA/OCTOPUSSY/src/GatewayWP.cc new file mode 100755 index 0000000000000000000000000000000000000000..bdb53043299df52bda64381d11a6b15271ee1bd1 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/GatewayWP.cc @@ -0,0 +1,898 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C90BFDD0240.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C90BFDD0240.cm + +//## begin module%3C90BFDD0240.cp preserve=no +//## end module%3C90BFDD0240.cp + +//## Module: GatewayWP%3C90BFDD0240; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\GatewayWP.cc + +//## begin module%3C90BFDD0240.additionalIncludes preserve=no +//## end module%3C90BFDD0240.additionalIncludes + +//## begin module%3C90BFDD0240.includes preserve=yes +#include "Gateways.h" +//## end module%3C90BFDD0240.includes + +// GatewayWP +#include "OCTOPUSSY/GatewayWP.h" +//## begin module%3C90BFDD0240.declarations preserve=no +//## end module%3C90BFDD0240.declarations + +//## begin module%3C90BFDD0240.additionalDeclarations preserve=yes + +// all packet headers must start with this signature +static const char PacketSignature[] = "oMs"; + +const Timeval to_init(5.0), + to_write(5.0), + to_heartbeat(2.0); + +//## end module%3C90BFDD0240.additionalDeclarations + + +// Class GatewayWP + +GatewayWP::GatewayWP (Socket* sk) + //## begin GatewayWP::GatewayWP%3C95C53D00AE.hasinit preserve=no + //## end GatewayWP::GatewayWP%3C95C53D00AE.hasinit + //## begin GatewayWP::GatewayWP%3C95C53D00AE.initialization preserve=yes + : WorkProcess(AidGatewayWP),sock(sk) + //## end GatewayWP::GatewayWP%3C95C53D00AE.initialization +{ + //## begin GatewayWP::GatewayWP%3C95C53D00AE.body preserve=yes + memcpy(wr_header.signature,PacketSignature,sizeof(wr_header.signature)); + setState(0); + setPeerState(INITIALIZING); + peerlist = 0; + rprocess = rhost = 0; + //## end GatewayWP::GatewayWP%3C95C53D00AE.body +} + + +GatewayWP::~GatewayWP() +{ + //## begin GatewayWP::~GatewayWP%3C90BEF001E5_dest.body preserve=yes + if( sock ) + delete sock; + //## end GatewayWP::~GatewayWP%3C90BEF001E5_dest.body +} + + + +//## Other Operations (implementation) +void GatewayWP::init () +{ + //## begin GatewayWP::init%3CC9500602CC.body preserve=yes + // subscribe to local subscribe notifications and Bye messages + // (they will be forwarded to peer as-is) + subscribe(MsgSubscribe|AidWildcard,Message::LOCAL); + subscribe(MsgBye|AidWildcard,Message::LOCAL); + //## end GatewayWP::init%3CC9500602CC.body +} + +bool GatewayWP::start () +{ + //## begin GatewayWP::start%3C90BF460080.body preserve=yes + WorkProcess::start(); + // this must exist by now (client GWs are always started!) + ObjRef plref = dsp()->localData(GWPeerList)[0].ref(DMI::WRITE); + peerlist = dynamic_cast<DataRecord*>(plref.dewr_p()); + FailWhen(!peerlist,"Local peer-list does not seem to be a DataRecord"); + + // handle & ignore SIGURG -- out-of-band data on socket. + // addInput() will catch an exception on the fd anyway + addSignal(SIGURG,EV_IGNORE); + // ignore SIGPIPE, but maintain Socket's sigpipe counter + addSignal(SIGPIPE,EV_IGNORE,&sock->sigpipe_counter); + + // collect local subscriptions data and send it to peer + // iterate over all WPs to find total size of all subscriptions + size_t nwp = 0, datasize = 0; + Dispatcher::WPIter iter = dsp()->initWPIter(); + WPID id; + const WPInterface *pwp; + + while( dsp()->getWPIter(iter,id,pwp) ) + { + if( id.wpclass() != AidGatewayWP ) // ignore gateway WPs + { + nwp++; + datasize += pwp->getSubscriptions().packSize() + pwp->address().packSize(); + } + } + size_t hdrsize = (1+2*nwp)*sizeof(size_t); + // form block containing addresses and subscriptions + SmartBlock *block = new SmartBlock(hdrsize+datasize); + BlockRef blockref(block,DMI::ANON); + size_t *hdr = static_cast<size_t*>(block->data()); + char *data = static_cast<char*>(block->data()) + hdrsize; + *(hdr++) = nwp; + iter = dsp()->initWPIter(); + while( dsp()->getWPIter(iter,id,pwp) ) + if( id.wpclass() != AidGatewayWP ) // ignore gateway WPs + { + data += *(hdr++) = pwp->address().pack(data,datasize); + data += *(hdr++) = pwp->getSubscriptions().pack(data,datasize); + } + Assert( !datasize ); + dprintf(1)("generating init message for %d subscriptions, block size %d\n", + nwp,hdrsize+datasize); + // put this block into a message and send it to peer + MessageRef msg(new Message(AidSubscriptions,blockref),DMI::ANON|DMI::WRITE); + msg().setFrom(address()); + msg()[AidPeers] = plref.copy(DMI::READONLY); + prepareMessage(msg); + + // init timeouts + addTimeout(to_init,AidInit,EV_ONESHOT); + addTimeout(to_heartbeat,AidHeartbeat,EV_CONT); + + // start watching the socket fd + addInput(sock->getSid(),EV_FDREAD|EV_FDWRITE|EV_FDEXCEPTION); + write_seq = 0; + read_junk = 0; + readyForHeader(); + + // init the status counters + statmon.counter = 0; + statmon.read = statmon.written = 0; + statmon.ts = Timestamp::now(); + return False; + //## end GatewayWP::start%3C90BF460080.body +} + +void GatewayWP::stop () +{ + //## begin GatewayWP::stop%3C90BF4A039D.body preserve=yes + if( sock ) + delete sock; + sock = 0; + read_bset.clear(); + write_queue.clear(); + //## end GatewayWP::stop%3C90BF4A039D.body +} + +bool GatewayWP::willForward (const Message &msg) const +{ + //## begin GatewayWP::willForward%3C90BF5C001E.body preserve=yes + if( peerState() != CONNECTED ) + return False; + // We're doing a simple everybody-connects-to-everybody topology. + // This determines the logic below: + dprintf(3)("willForward(%s)",msg.sdebug(1).c_str()); + // Normally, messages will only be forwarded once (i.e, only + // when hopcount=0). + // GwServerBound are the exception: they're forwarded up to three times. + // This insures that when, e.g, the following link ("=") is established: + // A1\ /B1 + // A0 = B0 + // A2/ \B2 + // ... A1/A2/B1/B2 can quickly learn about each other's server ports. + if( msg.id().matches(MsgGWServerOpen|AidWildcard) ) + { + if( msg.forwarder() == address() ) + { + dprintf(3)("no, we were the forwarder\n"); + return False; + } + if( msg.hops() > 3 ) + { + dprintf(3)("no, hopcount = %d\n",msg.hops() ); + return False; + } + } + else if( msg.hops() > 0 ) + { + dprintf(3)("no, non-local origin, hopcount = %d\n",msg.hops() ); + return False; + } + // Check that to-scope of message matches remote + if( !rprocess.matches( msg.to().process() ) || + !rhost.matches( msg.to().host() ) ) + { + dprintf(3)("no, `to' does not match remote %s.%s\n", + rprocess.toString().c_str(),rhost.toString().c_str()); + return False; + } + // if message is published, search thru remote subscriptions + if( msg.to().wpclass() == AidPublish ) + { + for( CRSI iter = remote_subs.begin(); iter != remote_subs.end(); iter++ ) + if( iter->second.matches(msg) ) + { + dprintf(3)("yes, subscribed to by remote %s\n",iter->first.toString().c_str()); + return True; + } + dprintf(3)("no, no remote subscribers\n"); + } + else // else check for match with a remote address + { + for( CRSI iter = remote_subs.begin(); iter != remote_subs.end(); iter++ ) + if( iter->first.matches(msg.to()) ) + { + dprintf(3)("yes, `to' address matches remote %s\n", + iter->first.toString().c_str()); + return True; + } + dprintf(3)("no, no matching remote WPs\n"); + } + return False; + //## end GatewayWP::willForward%3C90BF5C001E.body +} + +int GatewayWP::receive (MessageRef& mref) +{ + //## begin GatewayWP::receive%3C90BF63005A.body preserve=yes + // ignore any messages out of the remote's scope + if( !rprocess.matches(mref->to().process()) || + !rhost.matches(mref->to().host()) ) + { + dprintf(3)("ignoring [%s]: does not match remote process/host\n",mref->sdebug(1).c_str()); + return Message::ACCEPT; + } + // ignore any messages from GatewayWPs, with the exception of Remote.Up + if( mref->from().wpclass() == AidGatewayWP && + !mref->id().matches(MsgGWRemoteUp) ) + { + dprintf(3)("ignoring [%s]: from a gateway\n",mref->sdebug(1).c_str()); + return Message::ACCEPT; + } + // hold off while still initializing the connection + if( peerState() == INITIALIZING ) + return Message::HOLD; + // else ignore if not connected + else if( peerState() != CONNECTED ) + return Message::ACCEPT; + + if( writeState() != IDLE ) // writing something? + { + // hold off we already have a pending message + if( pending_msg.valid() ) + return Message::HOLD; + pending_msg.xfer(mref); + } + else // no, write state is idle, so start sending + { + prepareMessage(mref); + dprintf(5)("enabling write input on socket\n"); + addInput(sock->getSid(),EV_FDWRITE); // enable write input + Timestamp::now(&last_write_to); + } + return Message::ACCEPT; + //## end GatewayWP::receive%3C90BF63005A.body +} + +int GatewayWP::timeout (const HIID &id) +{ + //## begin GatewayWP::timeout%3C90BF6702C3.body preserve=yes + if( id == AidInit ) // connection timeout + { + if( peerState() == INITIALIZING ) + { + lprintf(1,"error: timed out waiting for init message from peer\n"); + shutdown(); + } + return Message::CANCEL; + } + else if( id == AidHeartbeat ) // heartbeat + { + // check that write is not blocked + if( writeState() != IDLE && Timestamp::now() - last_write_to >= to_write ) + { + lprintf(1,"error: timed out waiting for write()\n"); + shutdown(); + } + // report on write queue status + if( (statmon.counter++)%4 == 0 ) + { + double now = Timestamp::now(), d = now - statmon.ts; + lprintf(3,"%.2f seconds elapsed since last stats report\n" + "read %llu bytes (%.3f MB/s)\n" + "wrote %llu bytes (%.3f MB/s)\n", + d,statmon.read,statmon.read/(1024*1024*d), + statmon.written,statmon.written/(1024*1024*d)); + statmon.ts = now; + statmon.read = statmon.written = 0; + } + } + return Message::ACCEPT; + //## end GatewayWP::timeout%3C90BF6702C3.body +} + +int GatewayWP::input (int fd, int flags) +{ + //## begin GatewayWP::input%3C90BF6F00ED.body preserve=yes + // in case we're shutting down, ignore the whole shebang + if( !sock ) + return Message::CANCEL; + // first handle out-of-band messages + if( flags&EV_FDEXCEPTION ) + { + flags &= ~EV_FDEXCEPTION; + // to be implemented + + } + // then handle writing + while( flags&EV_FDWRITE ) + { + // write is idle? disable the write input + if( writeState() == IDLE ) + { + dprintf(5)("write state is IDLE, removing input\n"); + removeInput(fd,EV_FDWRITE); + flags &= ~EV_FDWRITE; + continue; // call us again + } + // write data from current block + while( nwritten < write_buf_size ) + { + int n = sock->write(write_buf + nwritten,write_buf_size - nwritten); + dprintf(5)("write(buf+%d,%d)=%d\n",nwritten,write_buf_size-nwritten,n); + if( n < 0 ) + { + // on write error, just commit harakiri. GWClient/ServerWP will + // take care of reopening a connection, eventually + lprintf(1,"error: socket write(): %s. Aborting.\n",sock->errstr().c_str()); + shutdown(); + return Message::CANCEL; + } + else if( n == 0 ) // nothing written at all, so clear the write bit + { + flags &= ~EV_FDWRITE; + break; + } + else + { + statmon.written += n; + last_write_to = Timestamp::now(&last_write); + // update checksum and advance the nread pointer + #if GATEWAY_CHECKSUM + for( ; n>0; n--,nwritten++ ) + write_checksum += write_buf[nwritten]; + #else + nwritten += n; + #endif + } + } + // in case we broke out of the loop + if( nwritten < write_buf_size ) + break; + // chunk written, advance to next one? + if( writeState() == HEADER ) + { + if( !write_queue.size() ) // were sending header but queue is empty + { + // if GW is being closed, detach now + if( peerState() == CLOSING ) + { + lprintf(2,LogError,"write finished, shutting down"); + detachMyself(); + return Message::ACCEPT; + } + // make sure we haven't been sending a data header + FailWhen(wr_header.type == MT_DATA,"write queue empty after data header"); + dprintf(5)("wrote lone header, now IDLE\n"); + setWriteState( IDLE ); + } + else // were sending header and queue is not empty, must be data header then + { + FailWhen(wr_header.type != MT_DATA,"write queue unexpectedly not empty"); + prepareData(); + } + } + else if( writeState() == BLOCK ) + { + prepareTrailer(); // after block, send trailer + } + else if( writeState() == TRAILER ) + { + // if GW is being closed, detach now + if( peerState() == CLOSING ) + { + lprintf(2,LogError,"write finished, shutting down"); + detachMyself(); + return Message::ACCEPT; + } + // something else in queue? send next header + if( write_queue.size() ) + prepareHeader(); + else + { + dprintf(5)("nothing else in write queue, now IDLE\n"); + setWriteState( IDLE ); + } + } + // have we changed state to IDLE? + if( writeState() == IDLE ) + { + if( pending_msg.valid() ) // send pending message, if any + prepareMessage(pending_msg); + } + } + // now handle reading + while( flags&EV_FDREAD ) + { + // read up to full buffer + while( nread < read_buf_size ) + { + int n = sock->read(read_buf + nread,read_buf_size - nread); + dprintf(5)("read(buf+%d,%d)=%d\n",nread,read_buf_size-nread,n); + if( n < 0 ) + { + // on read error, just commit harakiri. GWClient/ServerWP will + // take care of reopening a connection, eventually + lprintf(1,"error: socket read(): %s. Aborting.\n",sock->errstr().c_str()); + shutdown(); + return Message::CANCEL; + } + else if( n == 0 ) // nothing read at all, so clear the read bit + { + flags &= ~EV_FDREAD; + break; + } + else // read something + { + statmon.read += n; + Timestamp::now(&last_read); + // update checksum and advance the nread pointer + #if GATEWAY_CHECKSUM + for( ; n>0; n--,nread++ ) + read_checksum += read_buf[nread]; + #else + nread += n; + #endif + } + } + // in case we broke out of the loop + if( nread < read_buf_size ) + break; + // since we got here, we have a complete buffer, so dispose of it according to mode + if( readState() == HEADER ) // got a packet header? + { + if( memcmp(header.signature,PacketSignature,sizeof(header.signature)) || + header.type > MT_MAXTYPE ) + { + dprintf(5)("header does not start with signature\n"); + // invalid header -- flush it + if( !read_junk ) + { + dprintf(2)("error: junk data before header\n"); + requestResync(); // request resync if this is first instance + } + // look for first byte of signature in this header + void *pos = memchr(&header,PacketSignature[0],sizeof(header)); + if( !pos ) // not found? flush everything + { + dprintf(5)("no signature found, flushing everything\n"); + nread = 0; + read_junk += sizeof(header); + } + else + { // else flush everything up to matching byte + int njunk = static_cast<char*>(pos) - reinterpret_cast<char*>(&header); + nread = sizeof(header) - njunk; + read_junk += njunk; + memmove(&header,pos,nread); + dprintf(5)("signature found, flushing %d junk bytes\n",njunk); + } + // retry + return input(fd,flags); + } + // else header is valid + if( read_junk ) + { // got any junk before it? report it + lprintf(2,"warning: %d junk bytes before header were discarded\n",read_junk); + read_junk = 0; + } + Timestamp::now(&last_read); + switch( header.type ) + { + case MT_PING: + dprintf(5)("PING packet, ignoring\n"); + break; // ignore ping message + + case MT_DATA: // data block coming up + readyForData(header); // sets buffers and read states accordingly + break; + + case MT_ACK: // acknowledgement of data message + dprintf(5)("ACK packet, ignoring\n"); + // to do later + case MT_RETRY: // retry data message + dprintf(5)("RETRY packet, ignoring\n"); + // to do later + break; + default: + lprintf(2,"warning: unknown packet type %d, ignoring\n",header.type); + } + } // end if( readState() == HEADER ) + else if( readState() == BLOCK ) + { + incoming_checksum = read_checksum; + readyForTrailer(); // sets buffers and read states accordingly + } + else if( readState() == TRAILER ) + { + // to do: check sequence number + // verify checksum + #if GATEWAY_CHECKSUM + if( incoming_checksum == trailer.checksum ) + #endif + { + dprintf(4)("received block #%d of size %d, checksum OK\n", + trailer.seq,read_bset.back()->size()); +// acknowledge(True); // reply with acknowledgment + if( trailer.msgsize ) // accumulated a complete message? + { + if( read_bset.size() != trailer.msgsize ) + { // major oops + lprintf(1,"error: block count mismatch, expected %d got %d\n", + trailer.msgsize,read_bset.size()); + // NB: DO SOMETHING VIOLENT HERE!! + read_bset.clear(); + } + else + { + processIncoming(); // process the incoming message + // if peer is being closed, return immediately + if( peerState() == CLOSING ) + return Message::CANCEL; + } + } + // expect header next + readyForHeader(); // sets buffers and read states accordingly + } + #if GATEWAY_CHECKSUM + else + { + dprintf(2)("block #%d: bad checksum\n",trailer.seq); + requestRetry(); // ask for retry, clear buffer + } + #endif + } + else + Throw("unexpected read state"); + } + return Message::ACCEPT; + //## end GatewayWP::input%3C90BF6F00ED.body +} + +// Additional Declarations + //## begin GatewayWP%3C90BEF001E5.declarations preserve=yes +int GatewayWP::requestResync () +{ + // Should eventually send an OOB message for a resync. + // For now, just start looking for a header + return readyForHeader(); +} + +int GatewayWP::requestRetry () +{ + // Should eventually send an OOB message for a retransmit. + // For now, just fllush incoming blocks and start looking for a header. + read_bset.clear(); + return readyForHeader(); +} + +int GatewayWP::readyForHeader () +{ + read_buf_size = sizeof(header); + read_buf = reinterpret_cast<char*>(&header); + nread = 0; + setReadState( HEADER ); + dprintf(5)("read state is now HEADER\n"); + return 0; +} + +int GatewayWP::readyForTrailer () +{ + read_buf_size = sizeof(trailer); + read_buf = reinterpret_cast<char*>(&trailer); + nread = 0; + setReadState( TRAILER ); + dprintf(5)("read state is now TRAILER\n"); + return 0; +} + +int GatewayWP::readyForData ( const PacketHeader &hdr ) +{ + read_buf_size = hdr.content; + if( read_buf_size > MaxBlockSize ) + { + lprintf(1,"error: block size too big (%d), aborting\n",read_buf_size); + return requestResync(); + } + nread = 0; + SmartBlock * bl = new SmartBlock(read_buf_size); + read_bset.pushNew().attach(bl,DMI::ANON|DMI::WRITE); + read_buf = static_cast<char*>(bl->data()); + setReadState( BLOCK ); + dprintf(5)("read state is now BLOCK\n"); + read_checksum = 0; + return 0; +} + +void GatewayWP::prepareMessage (MessageRef &mref) +{ + FailWhen(write_queue.size(),"write queue is not empty??"); + dprintf(5)("write-queueing [%s]\n",mref->sdebug(1).c_str()); + // convert the message to blocks, placing them into the write queue + write_msgsize = mref->toBlock(write_queue); + // release ref, so as to minimize the blocks' ref counts + mref.detach(); + // privatize the queue + write_queue.privatizeAll(DMI::READONLY); + // start sending + prepareHeader(); +} + + +void GatewayWP::prepareHeader () +{ + if( !write_queue.size() ) + { + wr_header.type = MT_PING; + wr_header.content = 0; + } + else + { + wr_header.type = MT_DATA; + wr_header.content = write_queue.front()->size(); + } + write_buf = reinterpret_cast<char*>(&wr_header); + write_buf_size = sizeof(wr_header); + write_checksum = 0; + nwritten = 0; + setWriteState( HEADER ); + dprintf(5)("write state is now HEADER\n"); +} + +void GatewayWP::prepareData () +{ + const BlockRef & ref = write_queue.front(); + write_buf = static_cast<const char *>(ref->data()); + write_buf_size = ref->size(); + FailWhen(write_buf_size>MaxBlockSize,"block size too large"); + write_checksum = 0; + nwritten = 0; + setWriteState( BLOCK ); + dprintf(5)("write state is now BLOCK\n"); +} + +void GatewayWP::prepareTrailer () +{ + write_queue.pop(); + wr_trailer.seq = write_seq++; + wr_trailer.checksum = write_checksum; + if( write_queue.size() ) // something left in queue? + wr_trailer.msgsize = 0; + else + wr_trailer.msgsize = write_msgsize; + write_buf = reinterpret_cast<char*>(&wr_trailer); + write_buf_size = sizeof(wr_trailer); + write_checksum = 0; + nwritten = 0; + setWriteState( TRAILER ); + dprintf(5)("write state is now TRAILER\n"); +} + +void GatewayWP::processIncoming() +{ + MessageRef ref = MessageRef(new Message,DMI::ANON|DMI::WRITE); + ref().fromBlock(read_bset); + Message &msg = ref; + msg.setForwarder(address()); + msg.addHop(); // increment message hop-count + dprintf(5)("received from remote [%s]\n",msg.sdebug(1).c_str()); + if( read_bset.size() ) + { + lprintf(2,"warning: %d unclaimed incoming blocks were discarded\n",read_bset.size()); + read_bset.clear(); + } +// if connected, it is a true remote message, so send it off + if( peerState() == CONNECTED ) + { + // Bye message from remote: drop WP from routing table + if( msg.id().prefixedBy(MsgBye) ) + { + RSI iter = remote_subs.find(msg.from()); + if( iter == remote_subs.end() ) + lprintf(1,"warning: got Bye [%s] from unknown remote WP\n",msg.sdebug(1).c_str()); + else + { + dprintf(2)("got Bye [%s], deleting routing entry\n",msg.sdebug(1).c_str()); + remote_subs.erase(iter); + } + } + // Subscribe message from remote: update table + else if( msg.id().prefixedBy(MsgSubscribe) ) + { + // unpack subscriptions block, catching any exceptions + Subscriptions subs; + bool success = False; + if( msg.data() ) + { + try { + subs.unpack(msg.data(),msg.datasize()); + success = True; + } catch( std::exception &exc ) { + lprintf(2,"warning: failed to unpack Subscribe message: %s\n",exc.what()); + } + } + if( success ) + { + dprintf(2)("got Subscriptions [%s]: %d subscriptions\n", + msg.sdebug(1).c_str(),subs.size()); + RSI iter = remote_subs.find(msg.from()); + if( iter == remote_subs.end() ) + { + dprintf(2)("inserting new entry into routing table\n"); + remote_subs[msg.from()] = subs; + } + else + { + dprintf(2)("updating entry in routing table\n"); + iter->second = subs; + } + } + else + { + lprintf(2,"warning: ignoring bad Subscriptions message [%s]\n",msg.sdebug(1).c_str()); + } + } + // send the message on, regardless of the above + // (call Dispatcher directly in order to bypass WPInterface::send, + // thus retaining the original from address and hopcount) + dsp()->send(ref,msg.to()); + } +// if initializing, then it must be a Subscriptions message from peer +// (see start(), above) + else if( peerState() == INITIALIZING ) + { + dprintf(1)("received init message from peer: %s\n",msg.sdebug(1).c_str()); + if( msg.id() != HIID(AidSubscriptions) ) + { + lprintf(1,"error: unexpected init message\n"); + shutdown(); + return; + } + // catch all exceptions during processing of init message + try + { + // remote peer process/host id + rprocess = msg.from().process(); + rhost = msg.from().host(); + HIID peerid(rprocess|rhost); + // paranoid case: if we already have a connection to the peer, shutdown + // (this really ought not to happen) + if( (*peerlist)[peerid].exists() ) + { + lprintf(1,LogError,"already connected to %s (%s:%d %s), closing gateway", + peerid.toString().c_str(), + (*peerlist)[peerid][AidHost].as_string().c_str(), + (*peerlist)[peerid][AidPort].as_int(), + (*peerlist)[peerid][AidTimestamp].as_Timestamp().toString("%T").c_str()); + Message *msg1 = new Message(MsgGWRemoteDuplicate|peerid); + MessageRef mref1; mref1 <<= msg1; + (*msg1)[AidHost] = sock->host(); + (*msg1)[AidPort] = atoi(sock->port().c_str()); + publish(mref1,Message::LOCAL); + setPeerState(CLOSING); + // if not writing anything, detach ourselves immediately + if( writeState() == IDLE ) + { + lprintf(2,LogError,"shutting down immediately"); + detachMyself(); + } + else + { + // else stop reading, and allow the writing to finish + lprintf(2,LogError,"will shut down once write is complete"); + removeInput(sock->getSid(),EV_FDREAD); + } + return; + } + // add this connection to the local peerlist + DataRecord *rec = new DataRecord; + (*peerlist)[peerid] <<= rec; + (*rec)[AidTimestamp] = Timestamp::now(); + (*rec)[AidHost] = sock->host(); + (*rec)[AidPort] = atoi(sock->port().c_str()); + // process remote subscriptions data + processInitMessage(msg.data(),msg.datasize()); + // set states + setPeerState(CONNECTED); + lprintf(2,("connected to remote peer " + msg.from().toString() + + "; initialized routing for %d remote WPs\n").c_str(), + remote_subs.size()); + // re-publish the init message as Remote.Up + msg.setId(MsgGWRemoteUp|peerid); + msg[AidHost] = sock->host(); + msg[AidPort] = atoi(sock->port().c_str()); + publish(ref,Message::GLOBAL); + } + catch( std::exception &exc ) + { + lprintf(1,"error: processing init message: %s\n",exc.what()); + shutdown(); + return; + } + // publish (locally only) fake Hello messages on behalf of remote WPs + for( CRSI iter = remote_subs.begin(); iter != remote_subs.end(); iter++ ) + { + MessageRef mref; + mref.attach(new Message(MsgHello|iter->first),DMI::ANON|DMI::WRITE ); + mref().setFrom(iter->first); + dsp()->send(mref,MsgAddress(AidPublish,AidPublish, + address().process(),address().host())); + } + // tell dispatcher that we can forward messages now + // (note that doing it here ensures that the GWRemoteUp message is + // only published to peers on "this" side of the connection) + dsp()->declareForwarder(this); + } + else + { + lprintf(1,"error: received remote message while in unexpected peer-state\n"); + shutdown(); + } +} + +// processes subscriptions contained in peer's init-message +// (the message block is formed in start(), above) +void GatewayWP::processInitMessage( const void *block,size_t blocksize ) +{ + FailWhen( !block,"no block" ); + size_t hdrsize; + const size_t *hdr = static_cast<const size_t *>(block); + int nwp; + // big enough for header? + FailWhen( blocksize < sizeof(size_t) || + blocksize < ( hdrsize = (1 + 2*( nwp = *(hdr++) ))*sizeof(size_t) ), + "corrupt block"); + // scan addresses and subscription blocks + const char *data = static_cast<const char *>(block) + hdrsize, + *enddata = static_cast<const char *>(block) + blocksize; + for( int i=0; i<nwp; i++ ) + { + size_t asz = *(hdr++), ssz = *(hdr++); + // check block size again + FailWhen( data+asz+ssz > enddata,"corrupt block" ); + // unpack address + MsgAddress addr; + addr.unpack(data,asz); data += asz; + // unpack subscriptions + Subscriptions &subs(remote_subs[addr]); + subs.unpack(data,ssz); + data += ssz; + } + FailWhen(data != enddata,"corrupt block"); +} + +void GatewayWP::shutdown () +{ + if( peerState() == CONNECTED ) // publish a Remote.Down message + { + HIID peerid = rprocess|rhost; + lprintf(1,"shutting down connection to %s",(rprocess|rhost).toString().c_str()); + MessageRef mref(new Message(MsgGWRemoteDown|peerid),DMI::ANON); + (*peerlist)[peerid].remove(); + publish(mref,Message::LOCAL); + } + else + lprintf(1,"shutting down"); + setPeerState(CLOSING); + detachMyself(); +} + + //## end GatewayWP%3C90BEF001E5.declarations +//## begin module%3C90BFDD0240.epilog preserve=yes +//## end module%3C90BFDD0240.epilog diff --git a/CEP/CPA/OCTOPUSSY/src/GatewayWP.h b/CEP/CPA/OCTOPUSSY/src/GatewayWP.h new file mode 100755 index 0000000000000000000000000000000000000000..cfc069bdc4b0e360417cb22a70f4e2c44ab975db --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/GatewayWP.h @@ -0,0 +1,237 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C90BFDD0236.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C90BFDD0236.cm + +//## begin module%3C90BFDD0236.cp preserve=no +//## end module%3C90BFDD0236.cp + +//## Module: GatewayWP%3C90BFDD0236; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\GatewayWP.h + +#ifndef GatewayWP_h +#define GatewayWP_h 1 + +//## begin module%3C90BFDD0236.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C90BFDD0236.additionalIncludes + +//## begin module%3C90BFDD0236.includes preserve=yes +//## end module%3C90BFDD0236.includes + +// Socket +#include "OCTOPUSSY/Net/Socket.h" +// Subscriptions +#include "OCTOPUSSY/Subscriptions.h" +// WorkProcess +#include "OCTOPUSSY/WorkProcess.h" +//## begin module%3C90BFDD0236.declarations preserve=no +//## end module%3C90BFDD0236.declarations + +//## begin module%3C90BFDD0236.additionalDeclarations preserve=yes +#pragma aid Subscriptions Init Heartbeat +//## end module%3C90BFDD0236.additionalDeclarations + + +//## begin GatewayWP%3C90BEF001E5.preface preserve=yes +//## end GatewayWP%3C90BEF001E5.preface + +//## Class: GatewayWP%3C90BEF001E5 +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +class GatewayWP : public WorkProcess //## Inherits: <unnamed>%3C90BF100390 +{ + //## begin GatewayWP%3C90BEF001E5.initialDeclarations preserve=yes + //## end GatewayWP%3C90BEF001E5.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: GatewayWP%3C95C53D00AE + GatewayWP (Socket* sk); + + //## Destructor (generated) + ~GatewayWP(); + + + //## Other Operations (specified) + //## Operation: init%3CC9500602CC + virtual void init (); + + //## Operation: start%3C90BF460080 + virtual bool start (); + + //## Operation: stop%3C90BF4A039D + virtual void stop (); + + //## Operation: willForward%3C90BF5C001E + // Returns True if this WP will forward this non-local message. + virtual bool willForward (const Message &msg) const; + + //## Operation: receive%3C90BF63005A + virtual int receive (MessageRef& mref); + + //## Operation: timeout%3C90BF6702C3 + virtual int timeout (const HIID &id); + + //## Operation: input%3C90BF6F00ED + virtual int input (int fd, int flags); + + // Additional Public Declarations + //## begin GatewayWP%3C90BEF001E5.public preserve=yes + //## end GatewayWP%3C90BEF001E5.public + + protected: + // Additional Protected Declarations + //## begin GatewayWP%3C90BEF001E5.protected preserve=yes + // packet header structure + typedef struct { char signature[3]; + uchar type; + long content; + } PacketHeader; + + // data block trailer structure + typedef struct { int seq; + long checksum; + int msgsize; + } DataTrailer; + + + typedef enum { MT_PING=0,MT_DATA=1,MT_ACK=2,MT_RETRY=3, + MT_ABORT=4,MT_MAXTYPE=4 } PacketTypes; + + typedef enum { IDLE=0,HEADER=1,BLOCK=2,TRAILER=3 } DataState; + + typedef enum { INITIALIZING = 0, + CONNECTED = 1, + CONN_ERROR = 2, + CLOSING = 3 } PeerState; + + // closes down the gateway + void shutdown (); + + // Helper functions to get/set the state + // The read/write/peer states are maintained in the first, second and + // third byte of the overall WP state. + int readState () const { return state()&0xFF; }; + int writeState () const { return (state()&0xFF00)>>8; }; + int peerState () const { return (state()&0xFF0000)>>16; }; + + void setReadState (int st) { setState((state()&~0xFF)|st,True); }; + void setWriteState (int st) { setState((state()&~0xFF00)|(st<<8),True); }; + void setPeerState (int st) { setState((state()&~0xFF0000)|(st<<16)); }; + + // Helper functions for reading from socket + int requestResync (); // ask remote to abort & resync + int requestRetry (); // ask remote to resend last message + int readyForHeader (); // start looking for header + int readyForTrailer (); // peraprte to receive trailer + int readyForData (const PacketHeader &hdr); // prepare to receive data block + void processIncoming(); // unblocks and sends off incoming message + + // parses the initialization message + void processInitMessage( const void *block,size_t blocksize ); + + // Helper functions for writing to socket + void prepareMessage (MessageRef &mref); + void prepareHeader (); + void prepareData (); + void prepareTrailer (); + + // remote info + AtomicID rhost,rprocess; + + // incoming/outgoing packet header + PacketHeader header,wr_header; + // read buffer for data trailer + DataTrailer trailer,wr_trailer; + // max size of xmitted block. Anything bigger than that will cause + // an error (should be in shared memory!) + static const int MaxBlockSize = 512*1024*1024; + + // reading state + DataState readstate; + char *read_buf; + int read_buf_size, + nread, + read_junk; + long read_checksum, + incoming_checksum; + BlockSet read_bset; + + // writing state + DataState writestate; + const char *write_buf; + int write_buf_size,nwritten; + long write_checksum; + BlockSet write_queue; + int write_seq; // sequence number + int write_msgsize; + MessageRef pending_msg; // one pending write-slot + + // timestamps for pings + Timestamp last_read,last_write,last_write_to; + // this is is the status monitor + typedef struct { + int counter; + unsigned long long read,written; + double ts; + } StatMon; + StatMon statmon; + + //## end GatewayWP%3C90BEF001E5.protected + private: + //## Constructors (generated) + GatewayWP(); + + GatewayWP(const GatewayWP &right); + + //## Assignment Operation (generated) + GatewayWP & operator=(const GatewayWP &right); + + // Additional Private Declarations + //## begin GatewayWP%3C90BEF001E5.private preserve=yes + DataRecord *peerlist; + //## end GatewayWP%3C90BEF001E5.private + private: //## implementation + // Data Members for Associations + + //## Association: OCTOPUSSY::<unnamed>%3C9225740182 + //## Role: GatewayWP::sock%3C9225740345 + //## begin GatewayWP::sock%3C9225740345.role preserve=no private: Socket { -> 0..1RHgN} + Socket *sock; + //## end GatewayWP::sock%3C9225740345.role + + //## Association: OCTOPUSSY::<unnamed>%3C9B06A30088 + //## Role: GatewayWP::remote_subs%3C9B06A303D1 + //## begin GatewayWP::remote_subs%3C9B06A303D1.role preserve=no private: Subscriptions { -> 0..*VHgN} + map<MsgAddress,Subscriptions> remote_subs; + //## end GatewayWP::remote_subs%3C9B06A303D1.role + + // Additional Implementation Declarations + //## begin GatewayWP%3C90BEF001E5.implementation preserve=yes + typedef map<MsgAddress,Subscriptions>::iterator RSI; + typedef map<MsgAddress,Subscriptions>::const_iterator CRSI; + //## end GatewayWP%3C90BEF001E5.implementation +}; + +//## begin GatewayWP%3C90BEF001E5.postscript preserve=yes +//## end GatewayWP%3C90BEF001E5.postscript + +// Class GatewayWP + +//## begin module%3C90BFDD0236.epilog preserve=yes +//## end module%3C90BFDD0236.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/Gateways.h b/CEP/CPA/OCTOPUSSY/src/Gateways.h new file mode 100644 index 0000000000000000000000000000000000000000..d8995850605642a290c8a69d8d14827802dd44d4 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Gateways.h @@ -0,0 +1,68 @@ +#ifndef Gateways_h +#define Gateways_h 1 + +#include "DMI/HIID.h" +#include "OCTOPUSSY/AID-OCTOPUSSY.h" + +// this includes declarations common to all gateways + +// Use checksum in gateway transmissions? This increases CPU usage +// during local transfers by a factor of 2 +#define GATEWAY_CHECKSUM 0 + +// Re-advertise servers. If set, all open GWServers will publish +// a GW.Server.Bound message at regular intervals. This should re-enable +// any connections that have dropped out. Quite a paranoid feature +#define ADVERTISE_SERVERS 0 + +#pragma aid ConnectionMgrWP GWServerWP GWClientWP GatewayWP +#pragma aid GW Client Server Bind Error Fatal Bound Remote Up Down Network Type +#pragma aid Duplicate Host Port Peers Connected Connection Add Network Local Open + +// gateway-related messages +const HIID + // Messages published by server + // common prefix + MsgGWServer(AidGW|AidServer), + // This is used to advertise when a server socket has been bound... + MsgGWServerOpen(AidGW|AidServer|AidOpen), + // ...for local unix sockets + // Payload: [AidHost] = hostname (string), [AidPort] = port. + MsgGWServerOpenLocal(MsgGWServerOpen|AidLocal), + // ...for network tcp sockets. Payload is the same, where + // "host" is the base path, and port is a socket number (i.e. the + // actual socket is available as host:port) + MsgGWServerOpenNetwork(MsgGWServerOpen|AidNetwork), + // common prefix for error messages + MsgGWServerError(MsgGWServer|AidError), + // bind() failed. Payload as above + MsgGWServerBindError(MsgGWServerError|AidBind), + // other (fatal) error. Payload as above, plus [AidEerror] = error string + MsgGWServerFatalError(MsgGWServerError|AidFatal), + + // Messages generated by GatewayWPs + // Common prefix + MsgGWRemote(AidGW|AidRemote), + // Error: duplicate connection to remote peer. Payload: [AidHost], [AidPort], + // if this was a client connection + MsgGWRemoteDuplicate(MsgGWRemote|AidDuplicate), + // Connected to remote peer (GW.Remote.Up.process.host) + MsgGWRemoteUp(MsgGWRemote|AidUp), + // Disconnected from remote peer (GW.Remote.Down.process.host) + MsgGWRemoteDown(MsgGWRemote|AidDown), + + // Local data fieldnames + // list of connections + GWPeerList(AidGW|AidPeers), + // local server port (-1 when no server yet) + GWNetworkServer(AidGW|AidNetwork|AidPort), + GWLocalServer(AidGW|AidLocal|AidPort), + +// dummy const + GWNull(); + +// opens standard set of client/server gateways +class Dispatcher; +void initGateways (Dispatcher &dsp); + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/Glish/Glish.aidlist b/CEP/CPA/OCTOPUSSY/src/Glish/Glish.aidlist new file mode 100644 index 0000000000000000000000000000000000000000..66bbc41a285f112be922f61b3f84e017c39e3c88 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Glish/Glish.aidlist @@ -0,0 +1 @@ +GlishClientWP 179 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/Glish/Glish.aidlist:1 diff --git a/CEP/CPA/OCTOPUSSY/src/Glish/GlishClientWP.cc b/CEP/CPA/OCTOPUSSY/src/Glish/GlishClientWP.cc new file mode 100755 index 0000000000000000000000000000000000000000..6a0ad2f2cb64825122fccbc128c485cabced4c4f --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Glish/GlishClientWP.cc @@ -0,0 +1,643 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3CB562880397.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3CB562880397.cm + +//## begin module%3CB562880397.cp preserve=no +//## end module%3CB562880397.cp + +//## Module: GlishClientWP%3CB562880397; Package body +//## Subsystem: OCTOPUSSY::Glish%3CB5A6190195 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Glish\GlishClientWP.cc + +//## begin module%3CB562880397.additionalIncludes preserve=no +//## end module%3CB562880397.additionalIncludes + +//## begin module%3CB562880397.includes preserve=yes +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> +#include <aips/Glish.h> +#include <aips/Arrays/Array.h> + +#include <DMI/DataRecord.h> +#include <DMI/DataField.h> +#include <DMI/DynamicTypeManager.h> +//## end module%3CB562880397.includes + +// GlishClientWP +#include "OCTOPUSSY/Glish/GlishClientWP.h" +//## begin module%3CB562880397.declarations preserve=no +//## end module%3CB562880397.declarations + +//## begin module%3CB562880397.additionalDeclarations preserve=yes +static int dum = aidRegistry_Glish(); +//## end module%3CB562880397.additionalDeclarations + + +// Class GlishClientWP + +GlishClientWP::GlishClientWP (GlishSysEventSource *src, bool autostp, AtomicID wpc) + //## begin GlishClientWP::GlishClientWP%3CB562BB0226.hasinit preserve=no + //## end GlishClientWP::GlishClientWP%3CB562BB0226.hasinit + //## begin GlishClientWP::GlishClientWP%3CB562BB0226.initialization preserve=yes + : WorkProcess(wpc),evsrc(src),autostop_(autostp) + //## end GlishClientWP::GlishClientWP%3CB562BB0226.initialization +{ + //## begin GlishClientWP::GlishClientWP%3CB562BB0226.body preserve=yes + connected = evsrc->connected(); + has_events = False; + //## end GlishClientWP::GlishClientWP%3CB562BB0226.body +} + + +GlishClientWP::~GlishClientWP() +{ + //## begin GlishClientWP::~GlishClientWP%3CB5618B0373_dest.body preserve=yes + if( evsrc ) + delete evsrc; + //## end GlishClientWP::~GlishClientWP%3CB5618B0373_dest.body +} + + + +//## Other Operations (implementation) +bool GlishClientWP::start () +{ + //## begin GlishClientWP::start%3CBA97E70232.body preserve=yes + fd_set fdset; + FD_ZERO(&fdset); + if( evsrc->addInputMask(&fdset) ) + { + for( int fd=0; fd<FD_SETSIZE; fd++ ) + if( FD_ISSET(fd,&fdset) ) + { + dprintf(2)("adding input for fd %d\n",fd); + addInput(fd,EV_FDREAD); + } + } + else + { + dprintf(2)("no input fds indicated by GlishEventSource\n"); + } + // add a timeout to keep checking for connectedness + addTimeout(2.0,HIID(),EV_CONT); + + return False; + //## end GlishClientWP::start%3CBA97E70232.body +} + +void GlishClientWP::stop () +{ + //## begin GlishClientWP::stop%3CBABEA10165.body preserve=yes + if( evsrc && connected ) + evsrc->postEvent("exit",GlishValue()); + //## end GlishClientWP::stop%3CBABEA10165.body +} + +int GlishClientWP::input (int , int ) +{ + //## begin GlishClientWP::input%3CBACB920259.body preserve=yes + if( !evsrc->connected() ) + { + // got disconnected? + if( connected ) + dprintf(1)("disconnected from Glish process\n"); + shutdown(); + } + else + { + GlishSysEvent event; + // The event loop + // loop until the mex # of events is reached, or no more events + for( int i=0; i < MaxEventsPerPoll; i++ ) + if( !evsrc->nextGlishEvent(event,0) ) + { + has_events=False; // no events? reset flag and exit + break; + } + else // else process the event + { + dprintf(2)("got event '%s'\n", event.type().c_str()); +// oh fuck, thisreturns 0: +// GlishSysEventSource *src = event.glishSource(); + GlishSysEventSource *src = evsrc; + Bool result = True; // AIPS++ Bool + + if( event.type() == "shutdown" ) // shutdown event + { + shutdown(); + } + else + { + try // catch all event processing exceptions + { + // all other events must carry a GlishRecord + FailWhen(event.valType() != GlishValue::RECORD,"event value not a record"); + // get the record out and process stuff + GlishRecord rec = event.val(); + GlishArray tmp; + if( event.type() == "subscribe" ) + { + FailWhen( rec.nelements() != 2,"illegal event value" ); + String idstr; int scope; + tmp = rec.get(0); tmp.get(idstr); + tmp = rec.get(1); tmp.get(scope); + HIID id(idstr); + FailWhen( !id.size(),"null HIID in subscribe" ); + subscribe(id,scope); + } + else if( event.type() == "unsubscribe" ) + { + FailWhen( rec.nelements() != 1,"illegal event value" ); + String idstr; + tmp = rec.get(0); tmp.get(idstr); + HIID id(idstr); + FailWhen( !id.size(),"null HIID in unsubscribe" ); + unsubscribe(id); + } + else if( event.type() == "send" ) + { + String tostr; + FailWhen(!rec.attributeExists("to"),"missing 'to' attribute"); + tmp = rec.getAttribute("to"); tmp.get(tostr); + HIID to(tostr); + FailWhen(!to.size(),"bad 'to' attribute"); + AtomicID wpi,process=AidLocal,host=AidLocal; + if( to.size() > 1 ) wpi = to[1]; + if( to.size() > 2 ) process = to[2]; + if( to.size() > 3 ) host = to[3]; + MessageRef ref = glishRecToMessage(rec); + setState(ref->state()); + send(ref,MsgAddress(to[0],wpi,process,host)); + } + else if( event.type() == "publish" ) + { + int scope; + FailWhen( !rec.attributeExists("scope"),"missing 'scope' attribute"); + tmp = rec.getAttribute("scope"); tmp.get(scope); + MessageRef ref = glishRecToMessage(rec); + setState(ref->state()); + publish(ref,scope); + } + else if( event.type() == "log" ) + { + FailWhen( rec.nelements() != 3,"illegal event value" ); + String msg,typestr; int level; + tmp = rec.get(0); tmp.get(msg); + tmp = rec.get(1); tmp.get(level); + tmp = rec.get(2); tmp.get(typestr); + AtomicID type(typestr); + log(msg,level,type); + } + else + Throw("unknown event"); + } // end try + catch ( std::exception &exc ) + { + dprintf(1)("error processing glish event, ignoring: %s\n",exc.what()); + result = False; + } + } + // if we fell through to here, return the reply + if( src->replyPending() ) + src->reply(GlishArray(result)); + } // end of event loop + } + return Message::ACCEPT; + //## end GlishClientWP::input%3CBACB920259.body +} + +int GlishClientWP::timeout (const HIID &) +{ + //## begin GlishClientWP::timeout%3CBACFC6013D.body preserve=yes + // fake an input all to check for connectedness, etc. + return input(0,0); + //## end GlishClientWP::timeout%3CBACFC6013D.body +} + +int GlishClientWP::receive (MessageRef &mref) +{ + //## begin GlishClientWP::receive%3CB5622B01ED.body preserve=yes + // if no connection, then just ignore it + if( !evsrc->connected() ) + { + dprintf(2)("not connected, ignoring [%s]\n",mref->sdebug(1).c_str()); + return Message::ACCEPT; + } + // wrap the message into a record and post it + GlishRecord rec; + if( messageToGlishRec(mref.deref(),rec) ) + { + evsrc->postEvent("receive",rec); + } + else + { + dprintf(1)("unable to convert [%s] to glish record\n",mref->sdebug(1).c_str()); + } + return Message::ACCEPT; + //## end GlishClientWP::receive%3CB5622B01ED.body +} + +MessageRef GlishClientWP::glishRecToMessage (const GlishRecord &glrec) +{ + //## begin GlishClientWP::glishRecToMessage%3CB57C8401D6.body preserve=yes + // get message attributes + FailWhen( !glrec.attributeExists("id") || + !glrec.attributeExists("priority"),"missing 'id' or 'priority' attribute"); + String idstr; + int priority,state=0; + GlishArray tmp; + tmp = glrec.getAttribute("id"); tmp.get(idstr); + tmp = glrec.getAttribute("priority"); tmp.get(priority); + if( glrec.attributeExists("state") ) + { + tmp = glrec.getAttribute("state"); tmp.get(state); + } + // setup message & ref + HIID id(idstr); + Message &msg = *new Message(id,priority); + MessageRef ref(msg,DMI::ANON|DMI::WRITE); + ref().setState(state); + // do we have a payload? + if( glrec.attributeExists("payload") ) + { + String typestr; + tmp = glrec.getAttribute("payload"); tmp.get(typestr); + TypeId tid(typestr); + // data record is unwrapped explicitly + if( tid == TpDataRecord ) + { + DataRecord *rec = new DataRecord; + msg <<= rec; + glishToRec(glrec,*rec); + } + else // else try to unblock the object + { + msg <<= blockRecToObject(glrec); + } + } + // do we have a data block as well? + if( glrec.attributeExists("datablock") ) + { + Array<uChar> data; + tmp = glrec.getAttribute("datablock"); tmp.get(data); + size_t sz = data.nelements(); + SmartBlock *block = new SmartBlock(sz); + msg <<= block; + if( sz ) + { + bool del; + const uChar *pdata = data.getStorage(del); + memcpy(block->data(),pdata,sz); + data.freeStorage(pdata,del); + } + } + return ref; + //## end GlishClientWP::glishRecToMessage%3CB57C8401D6.body +} + +bool GlishClientWP::messageToGlishRec (const Message &msg, GlishRecord &glrec) +{ + //## begin GlishClientWP::messageToGlishRec%3CB57CA00280.body preserve=yes + glrec.addAttribute("id",GlishArray(msg.id().toString())); + glrec.addAttribute("to",GlishArray(msg.id().toString())); + glrec.addAttribute("from",GlishArray(msg.from().toString())); + glrec.addAttribute("priority",GlishArray(msg.priority())); + glrec.addAttribute("state",GlishArray(msg.state())); + // convert payload + if( msg.payload().valid() ) + { + TypeId tid = msg.payload()->objectType(); + glrec.addAttribute("payload",GlishArray(tid.toString())); + // records are converted + if( tid == TpDataRecord ) + { + const DataRecord *rec = dynamic_cast<const DataRecord *>(msg.payload().deref_p()); + Assert(rec); + recToGlish(*rec,glrec); + } + else + { + objectToBlockRec(msg.payload().deref(),glrec); + } + } + // copy data block, if any + if( msg.block().valid() ) + { + size_t sz = msg.datasize(); + glrec.addAttribute("datasize",GlishArray((int)sz)); + if( sz ) + glrec.addAttribute("data",GlishArray(Array<uChar>(IPosition(1,sz), + static_cast<uChar*>(msg.data()),COPY))); + } + + return True; + //## end GlishClientWP::messageToGlishRec%3CB57CA00280.body +} + +// Additional Declarations + //## begin GlishClientWP%3CB5618B0373.declarations preserve=yes +void GlishClientWP::recToGlish (const DataRecord &rec, GlishRecord& glrec) +{ + DataRecord::Iterator iter = rec.initFieldIter(); + HIID id; + TypeId type; + int size; + while( rec.getFieldIter(iter,id,type,size) ) + { + string name = id.toString(); + GlishRecord subrec; + switch( (int)type ) + { + // subrecords are recursively expanded + case TpDataRecord_int: + { + if( size == 1 ) // one record mapped directly + { + recToGlish(rec[id].as_DataRecord(),subrec); + } + else // array of records mapped as record of records + { + subrec.addAttribute("fieldsize",GlishArray(size)); + for( int i=0; i<size; i++ ) + { + GlishRecord subsubrec; + recToGlish(rec[id][i].as_DataRecord(),subsubrec); + char num[32]; + sprintf(num,"%d",i); + subrec.add(num,subsubrec); + } + } + glrec.add(name,subrec); + break; + } + // primitive types passed as arrays + // (we cast away const, but that's OK since Array is constructed with COPY storage) + case Tpbool_int: + glrec.add(name,Array<Bool>(IPosition(1,size),const_cast<Bool*>(rec[id].as_bool_p()),COPY)); + break; + case Tpuchar_int: + glrec.add(name,Array<uChar>(IPosition(1,size),const_cast<uChar*>(rec[id].as_uchar_p()),COPY)); + break; + case Tpshort_int: + glrec.add(name,Array<Short>(IPosition(1,size),const_cast<Short*>(rec[id].as_short_p()),COPY)); + break; + case Tpint_int: + glrec.add(name,Array<Int>(IPosition(1,size),const_cast<Int*>(rec[id].as_int_p()),COPY)); + break; + case Tpfloat_int: + glrec.add(name,Array<Float>(IPosition(1,size),const_cast<Float*>(rec[id].as_float_p()),COPY)); + break; + case Tpdouble_int: + glrec.add(name,Array<Double>(IPosition(1,size),const_cast<Double*>(rec[id].as_double_p()),COPY)); + break; + case Tpfcomplex_int: + glrec.add(name,Array<Complex>(IPosition(1,size),const_cast<Complex*>(rec[id].as_fcomplex_p()),COPY)); + break; + case Tpdcomplex_int: + glrec.add(name,Array<DComplex>(IPosition(1,size),const_cast<DComplex*>(rec[id].as_dcomplex_p()),COPY)); + break; + case Tpstring_int: + { + // special case: convert strings to AIPS++ Strings + String *storage = new String[size]; + const string *ptr = &rec[id]; + for( int i=0; i<size; i++ ) + storage[i] = *ptr++; + glrec.add(name,Array<String>(IPosition(1,size),storage,TAKE_OVER)); + break; + } + // all unknown types passed as blocksets + default: + { + objectToBlockRec(rec[id].as_DataField(),subrec); + glrec.add(name,subrec); + break; + } + } + } +} + +// helper function to create a DataField from a GlishArray +template<class T> +static void newDataField( const GlishArray &arr,DataField &fld,TypeId tid,int n) +{ + Array<T> array; + arr.get(array); + bool del; + const T * data = array.getStorage(del); + fld.init(tid,n,static_cast<const void *>(data)); + array.freeStorage(data,del); +} + +void GlishClientWP::glishToRec (const GlishRecord &glrec, DataRecord& rec) +{ + for( uint i=0; i < glrec.nelements(); i++ ) + { + HIID id = glrec.name(i); + GlishValue val = glrec.get(i); + // arrays mapped to DataFields (NB: should also be DataArrays, once + // those are ready) + if( val.type() == GlishValue::ARRAY ) + { + GlishArray arr = val; + int n = arr.shape().product(); + DataField *fld = new DataField; + rec[id] <<= fld; + switch( arr.elementType() ) + { + case GlishArray::BOOL: + newDataField<Bool>(val,*fld,Tpbool,n); + break; + case GlishArray::BYTE: + newDataField<uChar>(val,*fld,Tpuchar,n); + break; + case GlishArray::SHORT: + newDataField<Short>(val,*fld,Tpshort,n); + break; + case GlishArray::INT: + newDataField<Int>(val,*fld,Tpint,n); + break; + case GlishArray::FLOAT: + newDataField<Float>(val,*fld,Tpfloat,n); + break; + case GlishArray::DOUBLE: + newDataField<Double>(val,*fld,Tpdouble,n); + break; + case GlishArray::COMPLEX: + newDataField<Complex>(val,*fld,Tpfcomplex,n); + break; + case GlishArray::DCOMPLEX: + newDataField<DComplex>(val,*fld,Tpdcomplex,n); + break; + case GlishArray::STRING: + { + // special case: convert AIPS++ Strings to strings + Array<String> array; + arr.get(array); + bool del; const String *data = array.getStorage(del); + fld = new DataField(Tpstring,n); + string *ptr = &(*fld)[HIID()]; + for( int i=0; i<n; i++ ) + *ptr++ = data[i]; + array.freeStorage(data,del); + break; + } + default: + Throw("unsupported array element type"); + } + } + else // initialize a record + { + GlishRecord glsubrec = val; + // interpret as field of several sub-records + if( glsubrec.attributeExists("fieldsize") ) + { + int nrec; + GlishArray tmp; + tmp = glsubrec.getAttribute("fieldsize"); tmp.get(nrec); + rec[id] <<= new DataField(TpDataRecord,nrec); + for( int i=0; i<nrec; i++ ) + { + GlishValue val = glsubrec.get(i); + if( val.type() != GlishValue::RECORD ) + { + dprintf(2)("warning: field is not a sub-record, ignoring\n"); + continue; + } + glishToRec(val,rec[id][i]); + } + } + else // interpret as single record + { + DataRecord *subrec = new DataRecord; + rec[id] <<= subrec; + glishToRec(glsubrec,*subrec); + } + } + } +} + +BlockableObject * GlishClientWP::blockRecToObject (const GlishRecord &rec ) +{ + FailWhen( !rec.attributeExists("blocktype"),"missing 'blocktype' attribute" ); + String typestr; + GlishArray tmp = rec.getAttribute("blocktype"); tmp.get(typestr); + TypeId tid(typestr); + FailWhen( !tid,"illegal blocktype "+typestr ); + // extract blockset form record + BlockSet set; + for( uint i=0; i<rec.nelements(); i++ ) + { + Array<uChar> arr; + tmp = rec.get(i); tmp.get(arr); + // create SmartBlock and copy data from array + size_t sz = arr.nelements(); + SmartBlock *block = new SmartBlock(sz); + set.pushNew().attach(block,DMI::WRITE|DMI::ANON); + if( sz ) + { + Bool del; + const uChar * data = arr.getStorage(del); + memcpy(block->data(),data,sz); + arr.freeStorage(data,del); + } + } + // create object & return + return DynamicTypeManager::construct(tid,set); +} + +void GlishClientWP::objectToBlockRec (const BlockableObject &obj,GlishRecord &rec ) +{ + BlockSet set; + obj.toBlock(set); + rec.addAttribute("blocktype",GlishArray(obj.objectType().toString())); + int i=0; + while( set.size() ) + { + char num[32]; + sprintf(num,"%d",i++); + rec.add("num",Array<uChar>(IPosition(1,set.front()->size()), + static_cast<uChar*>(set.front()->data()),COPY)); + set.pop(); + } +} + +void GlishClientWP::shutdown () +{ + dprintf(1)("shutting down\n"); + connected = False; + setState(-1); + removeInput(-1); + removeTimeout("*"); + if( autostop() ) + { + dprintf(1)("autostop is on: stopping the system\n"); + dsp()->stopPolling(); + } + else + { + dprintf(1)("detaching\n"); + detachMyself(); + } +} + + //## end GlishClientWP%3CB5618B0373.declarations +//## begin module%3CB562880397.epilog preserve=yes +GlishClientWP * makeGlishClientWP (int argc,const char *argv[] ) +{ + // stupid glish wants non-const argv + GlishSysEventSource *evsrc = + new GlishSysEventSource(argc,const_cast<char**>(argv)); + AtomicID wpc = AidGlishClientWP; + // scan arguments for an override + string wpcstr; + for( int i=1; i<argc; i++ ) + { + if( string(argv[i]) == "-wpc" && i < argc-1 ) + { + wpcstr = argv[i+1]; + break; + } + } + if( wpcstr.length() ) + wpc = AtomicID(wpcstr); + return new GlishClientWP(evsrc,wpc); +} +//## end module%3CB562880397.epilog + + +// Detached code regions: +#if 0 +//## begin GlishClientWP::getPollPriority%3CB562250343.body preserve=yes + return WorkProcess::getPollPriority(tick); + +// int pri = WorkProcess::getPollPriority(tick); +// // has something come up on the event stream? +// if( (connected && !evsrc->connected()) || evsrc->waitingEvent() ) +// { +// int pri2 = Message::PRI_NORMAL; +// // nominal priority of Glish events is NORMAL, however, +// // the event age is added in +// if( has_events ) +// pri2 += tick - evtick; +// else +// { +// has_events = True; +// evtick = tick; +// } +// pri = max(pri,pri2); +// } +// return pri; +//## end GlishClientWP::getPollPriority%3CB562250343.body + +//## begin GlishClientWP::poll%3CBAA3D701E6.body preserve=yes + return False; +//## end GlishClientWP::poll%3CBAA3D701E6.body + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/Glish/GlishClientWP.h b/CEP/CPA/OCTOPUSSY/src/Glish/GlishClientWP.h new file mode 100755 index 0000000000000000000000000000000000000000..6ce0df1d99854c8ccde40ea2a03da9b78fac139d --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Glish/GlishClientWP.h @@ -0,0 +1,164 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3CB562880395.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3CB562880395.cm + +//## begin module%3CB562880395.cp preserve=no +//## end module%3CB562880395.cp + +//## Module: GlishClientWP%3CB562880395; Package specification +//## Subsystem: OCTOPUSSY::Glish%3CB5A6190195 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Glish\GlishClientWP.h + +#ifndef GlishClientWP_h +#define GlishClientWP_h 1 + +//## begin module%3CB562880395.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3CB562880395.additionalIncludes + +//## begin module%3CB562880395.includes preserve=yes +#include "OCTOPUSSY/Glish/AID-Glish.h" +//## end module%3CB562880395.includes + +// WorkProcess +#include "OCTOPUSSY/WorkProcess.h" +//## begin module%3CB562880395.declarations preserve=no +//## end module%3CB562880395.declarations + +//## begin module%3CB562880395.additionalDeclarations preserve=yes +#pragma aidgroup Glish +#pragma aid GlishClientWP + +class GlishSysEventSource; +class GlishRecord; +//## end module%3CB562880395.additionalDeclarations + + +//## begin GlishClientWP%3CB5618B0373.preface preserve=yes +//## end GlishClientWP%3CB5618B0373.preface + +//## Class: GlishClientWP%3CB5618B0373 +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY::Glish%3CB5A6190195 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +class GlishClientWP : public WorkProcess //## Inherits: <unnamed>%3CB5619C036E +{ + //## begin GlishClientWP%3CB5618B0373.initialDeclarations preserve=yes + //## end GlishClientWP%3CB5618B0373.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: GlishClientWP%3CB562BB0226 + GlishClientWP (GlishSysEventSource *src, bool autostp = True, AtomicID wpc = AidGlishClientWP); + + //## Destructor (generated) + ~GlishClientWP(); + + + //## Other Operations (specified) + //## Operation: start%3CBA97E70232 + virtual bool start (); + + //## Operation: stop%3CBABEA10165 + virtual void stop (); + + //## Operation: input%3CBACB920259 + virtual int input (int , int ); + + //## Operation: timeout%3CBACFC6013D + virtual int timeout (const HIID &); + + //## Operation: receive%3CB5622B01ED + virtual int receive (MessageRef &mref); + + //## Operation: glishRecToMessage%3CB57C8401D6 + MessageRef glishRecToMessage (const GlishRecord &glrec); + + //## Operation: messageToGlishRec%3CB57CA00280 + bool messageToGlishRec (const Message &msg, GlishRecord &glrec); + + // Additional Public Declarations + //## begin GlishClientWP%3CB5618B0373.public preserve=yes + // max number of glish events processed per one polling loop + static const int MaxEventsPerPoll = 10; + + static void recToGlish (const DataRecord &rec, GlishRecord& glrec); + static void objectToBlockRec (const BlockableObject &obj,GlishRecord &rec ); + + //## end GlishClientWP%3CB5618B0373.public + protected: + // Additional Protected Declarations + //## begin GlishClientWP%3CB5618B0373.protected preserve=yes + void glishToRec (const GlishRecord &glrec, DataRecord& rec); + BlockableObject * blockRecToObject (const GlishRecord &rec ); + //## end GlishClientWP%3CB5618B0373.protected + private: + //## Constructors (generated) + GlishClientWP(); + + GlishClientWP(const GlishClientWP &right); + + //## Assignment Operation (generated) + GlishClientWP & operator=(const GlishClientWP &right); + + //## Get and Set Operations for Class Attributes (generated) + + //## Attribute: autostop%3CBAE1740040 + bool autostop () const; + + // Additional Private Declarations + //## begin GlishClientWP%3CB5618B0373.private preserve=yes + // shuts down the link + void shutdown (); + //## end GlishClientWP%3CB5618B0373.private + private: //## implementation + // Data Members for Class Attributes + + //## Attribute: evsrc%3CB561E2013E + //## begin GlishClientWP::evsrc%3CB561E2013E.attr preserve=no private: GlishSysEventSource * {U} + GlishSysEventSource *evsrc; + //## end GlishClientWP::evsrc%3CB561E2013E.attr + + //## begin GlishClientWP::autostop%3CBAE1740040.attr preserve=no private: bool {U} + bool autostop_; + //## end GlishClientWP::autostop%3CBAE1740040.attr + + // Additional Implementation Declarations + //## begin GlishClientWP%3CB5618B0373.implementation preserve=yes + // flag: have unprocessed events in the stream + bool connected,has_events; + // tick of oldest unprocessed event + ulong evtick; + //## end GlishClientWP%3CB5618B0373.implementation +}; + +//## begin GlishClientWP%3CB5618B0373.postscript preserve=yes +//## end GlishClientWP%3CB5618B0373.postscript + +// Class GlishClientWP + +//## Get and Set Operations for Class Attributes (inline) + +inline bool GlishClientWP::autostop () const +{ + //## begin GlishClientWP::autostop%3CBAE1740040.get preserve=no + return autostop_; + //## end GlishClientWP::autostop%3CBAE1740040.get +} + +//## begin module%3CB562880395.epilog preserve=yes +GlishClientWP * makeGlishClientWP (int argv,const char *argv[] ); +//## end module%3CB562880395.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/Glish/Makefile.am b/CEP/CPA/OCTOPUSSY/src/Glish/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..593a7054a5e93a0421482bf937189b24a8c2dc49 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Glish/Makefile.am @@ -0,0 +1,10 @@ +dmi_dir = $(lofar_sharedir)/../DMI + +CXXFLAGS += -Wall -Wno-unknown-pragmas + +lib_LTLIBRARIES = liboctopussy-glish.la + +liboctopussy_glish_la_SOURCES = GlishClientWP.cc AID-Glish-Registry.cc + +include $(lofar_sharedir)/Makefile.common + diff --git a/CEP/CPA/OCTOPUSSY/src/Glish/octopussy.g b/CEP/CPA/OCTOPUSSY/src/Glish/octopussy.g new file mode 100644 index 0000000000000000000000000000000000000000..ad5713718fce6c450712e870a25af820c7198f28 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Glish/octopussy.g @@ -0,0 +1,266 @@ + +pragma include once + +include "note.g"; + +octopussy := function (wpclass="",server="gloctopussy",options="",autoexit=T) +{ + self := [=]; + public := [=]; + + self.opClient := F; + self.opClient::Died := T; + self.state := 0; + +# Private functions +#------------------------------------------------------------------------------ + const self.makeclient := function (server,wpclass="",options="") + { + wider self; +# if( wpclass == "" ) { + print "starting client(",server,",",options,")"; + self.opClient := client(server,options); +# } else { +# print "starting client(",server,",-wpc,",wpclass,",",options; +# self.opClient := client(server,"-wpc",wpclass,options); +# } + print self.opClient; + if( !is_agent(self.opClient) ) + fail paste('server',server,'could not be started'); + print "connected"; + self.opClient::Died := F; + whenever self.opClient->fail do self.opClient::Died := T; + return T; + } + + const self.makemsg := function (id,rec=F,priority="normal",datablock=F,blockset=F) + { + wider self; + data := [=]; + if( !is_boolean(rec) ) + { + if( !is_boolean(blockset) ) + fail 'unable to send record and blockset together'; + data := rec; + data::payload := "DataRecord"; + } + else if( !is_boolean(blockset) ) + { + # NB: check for blocktype + data := blockset; + data::payload := blockset::blocktype; + } + if( !is_boolean(datablock) ) + { + data::datablock := datablock; + } + data::id := id; + data::priority := priority; + data::state := self.state; + return data; + } + + const self.getscope := function (scope) + { + sc := to_lower(scope); + if( sc == "local" || sc == "process" ) + return 0; + else if( sc == "host" ) + return 1; + else if( sc == "global" ) + return 2; + fail paste('illegal scope',scope); + } + + +# Public functions +#------------------------------------------------------------------------------ + const public.init := function (wpclass="",server="gloctopussy",options="") + { + wider self; + if( is_boolean(self.opClient) || self.opClient::Died ) + { + self.makeclient(server,wpclass=wpclass,options=options); + } + return T; + } + + const public.done := function () + { + self.opClient->terminate(); + } + + const public.subscribe := function (ids,scope="global") + { + # set the scope parameter + wider self; + sc := self.getscope(scope); + if( is_fail(sc) ) + fail sc; + for( id in ids ) + { + print "subscribing: ",id,sc; + # send event + if( !self.opClient->subscribe([id=id,scope=sc]) ) + fail 'subscribe() failed'; + } + return T; + } + + const public.unsubscribe := function (id) + { + wider self; + if( self.opClient->unsubscribe([id=id]) ) + return T; + else + fail 'unsubscribe() failed'; + } + + const public.log := function (msg,type="normal",level=1) + { + wider self; + # set the type + tp := to_lower(type); + if( tp == "normal" ) + tp := "LogNormal"; + else if( tp == "warn" || tp == "warning" ) + tp := "LogWarning"; + else if( tp == "error" ) + tp := "LogError"; + else if( tp == "debug" ) + tp := "LogDebug"; + else if( tp == "fatal" ) + tp := "LogFatal"; + else + fail paste('unknown log message type: ',type); + # send the event + if( self.opClient->log([msg=msg,level=level,type=tp]) ) + return T; + else + fail 'log() failed'; + } + + const public.send := function (id,dest,rec=F,priority="normal",datablock=F,blockset=F) + { + wider self; + rec := self.makemsg(id,rec,priority,datablock,blockset); + rec::to := dest; + # send the event + if( self.opClient->send(rec) ) + return T; + else + fail 'send() failed'; + } + + const public.publish := function (id,rec=F,scope="global",priority="normal",datablock=F,blockset=F) + { + # set the scope + print "publish: ",id,rec,scope; + wider self; + sc := self.getscope(scope); + if( is_fail(sc) ) + return sc; + # create message record + rec := self.makemsg(id,rec,priority,datablock,blockset); + rec::scope := sc; + print "publishing: ",rec,rec::; + # send the event + if( self.opClient->publish(rec) ) + return T; + else + fail 'send() failed'; + } + + const public.receive := function (autoexit=T) + { + wider self; + await self.opClient->receive,self.opClient->exit; + if( $name == "receive " ) + { + return $value; + } + else if( $name == "exit" ) + { + self.opClient::Died := T; + if( autoexit ) + { + print "Got 'exit' event, exiting"; + exit 1; + } + fail 'remote client has terminated'; + } + fail paste('unexpected event',$name); + } + + const public.state := function () + { + wider self; + return self.state; + } + + const public.setstate := function (newstate) + { + wider self; + wider public; + if( self.state != newstate ) + { + self.state := newstate; + return public.publish("WorkProcess.State"); + } + return T; + } + + const public.connected := function () + { + wider self; + return !self.opClient::Died; + } + + res := public.init(wpclass,server=server,options=options); + if( is_fail(res) ) + return res; + + if( autoexit ) + whenever self.opClient->exit do { + print "Got 'exit' event, exiting"; + exit 1; + } + + return public; +} + +test_octopussy := function (server="./test_glish",options="") +{ + oct := octopussy(server=server,options=options); + if( is_fail(oct) || !oct.connected() ) + fail 'unable to connect to server'; + oct.subscribe("Pong"); + # create a ping message + run := T; + count := 0; + while( run && count<5 ) + { + rec := [=]; + rec.Timestamp := 0; + rec.Invert := T; + rec.Data := random(10); + rec.Count := count; + count +:= 1; + res := oct.publish("Ping",rec); + if( is_fail(res) ) + print "publish failed",res; + msg := oct.receive(); + if( is_fail(msg) ) + { + print "Receive failed: ",msg; + run := F; + } + else + { + print "Received: ",msg; + } + } +} + +test_octopussy(); +exit 0; diff --git a/CEP/CPA/OCTOPUSSY/src/LoggerWP.cc b/CEP/CPA/OCTOPUSSY/src/LoggerWP.cc new file mode 100755 index 0000000000000000000000000000000000000000..095eee30fe85071bd7d75d75ac30ccb56de4f97c --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/LoggerWP.cc @@ -0,0 +1,224 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3CA045460090.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3CA045460090.cm + +//## begin module%3CA045460090.cp preserve=no +//## end module%3CA045460090.cp + +//## Module: LoggerWP%3CA045460090; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\LoggerWP.cc + +//## begin module%3CA045460090.additionalIncludes preserve=no +//## end module%3CA045460090.additionalIncludes + +//## begin module%3CA045460090.includes preserve=yes +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +//## end module%3CA045460090.includes + +// LoggerWP +#include "OCTOPUSSY/LoggerWP.h" +//## begin module%3CA045460090.declarations preserve=no +//## end module%3CA045460090.declarations + +//## begin module%3CA045460090.additionalDeclarations preserve=yes +//## end module%3CA045460090.additionalDeclarations + + +// Class LoggerWP + +LoggerWP::LoggerWP (int maxlev, int scope) + //## begin LoggerWP::LoggerWP%3CA0451401B9.hasinit preserve=no + //## end LoggerWP::LoggerWP%3CA0451401B9.hasinit + //## begin LoggerWP::LoggerWP%3CA0451401B9.initialization preserve=yes + : WorkProcess(AidLoggerWP), + level_(maxlev),consoleLevel_(-1),scope_(scope),fd(-1) + //## end LoggerWP::LoggerWP%3CA0451401B9.initialization +{ + //## begin LoggerWP::LoggerWP%3CA0451401B9.body preserve=yes + //## end LoggerWP::LoggerWP%3CA0451401B9.body +} + + +LoggerWP::~LoggerWP() +{ + //## begin LoggerWP::~LoggerWP%3CA044DE02AB_dest.body preserve=yes + if( fd >= 0 ) + close(fd); + //## end LoggerWP::~LoggerWP%3CA044DE02AB_dest.body +} + + + +//## Other Operations (implementation) +void LoggerWP::init () +{ + //## begin LoggerWP::init%3CA045020054.body preserve=yes + // default logname is app path + string filebase = config.appPath()+".log"; + filename_ = filebase; + // .. but can be overridden by config + config.get("logfile",filename_); + + // get log levels from config + config.get("loglev",level_); + config.get("logcon",consoleLevel_); + config.getOption("lc",consoleLevel_); + level_ = max(level_,consoleLevel_); + + config.getOption("logscope",scope_); + + dprintf(0)("log level: %d, console log level: %d, scope: %d\n", + level_,consoleLevel_,scope_); + + // subscribe to log messages + subscribe(MsgLog|AidWildcard,scope_); + + // try to open log file and grab a write-lock on it. If that fails, try + // "file.1", etc. This ensures that different processes do not write + // to the same log. + for( int filenum = 0; ; filenum++ ) + { + if( filenum ) + filename_ = filebase + Debug::ssprintf(".%d",filenum); + + // try to open the file + fd = open(filename_.c_str(),O_CREAT|O_WRONLY|O_APPEND,0644); + if( fd < 0 ) + { + dprintf(0)("open(%s): %d (%s)\n",filename_.c_str(),errno,strerror(errno)); + dprintf(0)("logging to file disabled\n"); + return; + } + // try to set write-lock + struct flock lock = { F_WRLCK,0,0,1,0 }; + if( fcntl(fd,F_SETLK,&lock) >= 0 ) // break out on success + break; + int err = errno; + if( fcntl(fd,F_GETLK,&lock) >= 0 ) + dprintf(0)("%s: already in use by pid %d\n",filename_.c_str(),lock.l_pid); + else + { + dprintf(0)("%s: failed to set lock: %s\n",filename_.c_str(),strerror(err)); + dprintf(0)("logging to file disabled\n"); + return; + } + close(fd); + } + dprintf(0)("opened log file %s\n",filename_.c_str()); + + // write header record + string hdr = Debug::ssprintf("%s|logger started, level=%d, scope=%d", + Timestamp::now().toString("%d/%m/%y").c_str(),level_,scope_); + struct stat st; + if( !fstat(fd,&st) && st.st_size > 0 ) + logMessage(address().toString(),"----------------------------------------------",0,LogNormal); + logMessage(address().toString(),hdr,0,LogNormal); + //## end LoggerWP::init%3CA045020054.body +} + +void LoggerWP::stop () +{ + //## begin LoggerWP::stop%3CA05A7E01CE.body preserve=yes + logMessage(address().toString(),"processing remaining messages",0,LogNormal); + MessageRef mref; + for(;;) + { + dequeue(MsgLog|AidWildcard,&mref); + if( mref.valid() ) + { + receive(mref); + mref.detach(); + } + else + break; + } + logMessage(address().toString(),"logger stopped",0,LogNormal); + if( fd >= 0 ) + close(fd); + fd = -1; + //## end LoggerWP::stop%3CA05A7E01CE.body +} + +int LoggerWP::receive (MessageRef &mref) +{ + //## begin LoggerWP::receive%3CA0450C0103.body preserve=yes + const Message &msg = mref.deref(); + // process Log messages, but ignore from myself + if( msg.id()[0] == MsgLog && msg.from() != address() ) + { + int idlen = msg.id().size(); + AtomicID type = idlen>1 ? msg.id()[1] : LogNormal; + int lev = idlen>2 ? msg.id()[2].id() : 0; + // compare to our log level + if( lev <= level() ) + { + string str(static_cast<const char*>(msg.data()),msg.datasize() ); + logMessage(msg.from().toString(),str,lev,type); + } + } + return Message::ACCEPT; + //## end LoggerWP::receive%3CA0450C0103.body +} + +void LoggerWP::setScope (int scope) +{ + //## begin LoggerWP::setScope%3CA04AF50212.body preserve=yes + unsubscribe(MsgLog|AidWildcard); + subscribe(MsgLog|AidWildcard,scope_=scope); + //## end LoggerWP::setScope%3CA04AF50212.body +} + +void LoggerWP::logMessage (const string &source, const string &msg, int level, AtomicID type) +{ + //## begin LoggerWP::logMessage%3CA04A1F03D7.body preserve=yes + string out = msg; + // chop off trailing newlines + while( out[out.length()-1] == '\n' ) + out.replace(out.length()-1,1,""); + + // chop redundancy off the type string + string ts = type.toString(); + if( ts.compare("Log",0,3) ) + ts = ts.substr(3); + + // form full output record + out = Timestamp::now().toString("%T|") + + source + "|" + ts + Debug::ssprintf("|%d|",level) + + ( out.length() ? out : string("{null message}") ) + "\n"; + + // log to console + if( level <= consoleLevel() ) + cerr<<">>>"<<out; + + // log to file + if( fd < 0 ) + return; + int res = write(fd,out.data(),out.length()); + if( res<0 ) + { + dprintf(0)("error writing to log file: %d (%s)\n",errno,strerror(errno)); + } + else if( res < (int)out.length() ) + { + dprintf(0)("error writing to log file: only %d of %d bytes written\n",res,out.length()); + } + //## end LoggerWP::logMessage%3CA04A1F03D7.body +} + +// Additional Declarations + //## begin LoggerWP%3CA044DE02AB.declarations preserve=yes + //## end LoggerWP%3CA044DE02AB.declarations + +//## begin module%3CA045460090.epilog preserve=yes +//## end module%3CA045460090.epilog diff --git a/CEP/CPA/OCTOPUSSY/src/LoggerWP.h b/CEP/CPA/OCTOPUSSY/src/LoggerWP.h new file mode 100755 index 0000000000000000000000000000000000000000..062df2b9ddbb3c4349cae15c1a111c2c72f55326 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/LoggerWP.h @@ -0,0 +1,169 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3CA04546008E.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3CA04546008E.cm + +//## begin module%3CA04546008E.cp preserve=no +//## end module%3CA04546008E.cp + +//## Module: LoggerWP%3CA04546008E; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\LoggerWP.h + +#ifndef LoggerWP_h +#define LoggerWP_h 1 + +//## begin module%3CA04546008E.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3CA04546008E.additionalIncludes + +//## begin module%3CA04546008E.includes preserve=yes +#include <stdio.h> +//## end module%3CA04546008E.includes + +// WorkProcess +#include "OCTOPUSSY/WorkProcess.h" +//## begin module%3CA04546008E.declarations preserve=no +//## end module%3CA04546008E.declarations + +//## begin module%3CA04546008E.additionalDeclarations preserve=yes +#pragma aid LoggerWP +//## end module%3CA04546008E.additionalDeclarations + + +//## begin LoggerWP%3CA044DE02AB.preface preserve=yes +//## end LoggerWP%3CA044DE02AB.preface + +//## Class: LoggerWP%3CA044DE02AB +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +class LoggerWP : public WorkProcess //## Inherits: <unnamed>%3CA044E9021B +{ + //## begin LoggerWP%3CA044DE02AB.initialDeclarations preserve=yes + //## end LoggerWP%3CA044DE02AB.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: LoggerWP%3CA0451401B9 + LoggerWP (int maxlev = 9999, int scope = Message::GLOBAL); + + //## Destructor (generated) + ~LoggerWP(); + + + //## Other Operations (specified) + //## Operation: init%3CA045020054 + virtual void init (); + + //## Operation: stop%3CA05A7E01CE + virtual void stop (); + + //## Operation: receive%3CA0450C0103 + virtual int receive (MessageRef &mref); + + //## Operation: setScope%3CA04AF50212 + void setScope (int scope); + + //## Operation: logMessage%3CA04A1F03D7 + virtual void logMessage (const string &source, const string &msg, int level, AtomicID type); + + //## Get and Set Operations for Class Attributes (generated) + + //## Attribute: level%3CA048E90395 + int level () const; + void setLevel (int value); + + //## Attribute: consoleLevel%3CA052560312 + int consoleLevel () const; + void setConsoleLevel (int value); + + // Additional Public Declarations + //## begin LoggerWP%3CA044DE02AB.public preserve=yes + //## end LoggerWP%3CA044DE02AB.public + + protected: + // Additional Protected Declarations + //## begin LoggerWP%3CA044DE02AB.protected preserve=yes + //## end LoggerWP%3CA044DE02AB.protected + + private: + //## Constructors (generated) + LoggerWP(const LoggerWP &right); + + //## Assignment Operation (generated) + LoggerWP & operator=(const LoggerWP &right); + + // Additional Private Declarations + //## begin LoggerWP%3CA044DE02AB.private preserve=yes + //## end LoggerWP%3CA044DE02AB.private + + private: //## implementation + // Data Members for Class Attributes + + //## begin LoggerWP::level%3CA048E90395.attr preserve=no public: int {U} + int level_; + //## end LoggerWP::level%3CA048E90395.attr + + //## begin LoggerWP::consoleLevel%3CA052560312.attr preserve=no public: int {U} + int consoleLevel_; + //## end LoggerWP::consoleLevel%3CA052560312.attr + + // Additional Implementation Declarations + //## begin LoggerWP%3CA044DE02AB.implementation preserve=yes + int scope_; + + string filename_; + int fd; + //## end LoggerWP%3CA044DE02AB.implementation +}; + +//## begin LoggerWP%3CA044DE02AB.postscript preserve=yes +//## end LoggerWP%3CA044DE02AB.postscript + +// Class LoggerWP + +//## Get and Set Operations for Class Attributes (inline) + +inline int LoggerWP::level () const +{ + //## begin LoggerWP::level%3CA048E90395.get preserve=no + return level_; + //## end LoggerWP::level%3CA048E90395.get +} + +inline void LoggerWP::setLevel (int value) +{ + //## begin LoggerWP::setLevel%3CA048E90395.set preserve=no + level_ = value; + //## end LoggerWP::setLevel%3CA048E90395.set +} + +inline int LoggerWP::consoleLevel () const +{ + //## begin LoggerWP::consoleLevel%3CA052560312.get preserve=no + return consoleLevel_; + //## end LoggerWP::consoleLevel%3CA052560312.get +} + +inline void LoggerWP::setConsoleLevel (int value) +{ + //## begin LoggerWP::setConsoleLevel%3CA052560312.set preserve=no + consoleLevel_ = value; + //## end LoggerWP::setConsoleLevel%3CA052560312.set +} + +//## begin module%3CA04546008E.epilog preserve=yes +//## end module%3CA04546008E.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/Makefile.am b/CEP/CPA/OCTOPUSSY/src/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..bcc92c45329108b6fade5a0a8b9275e13f9ea7c9 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Makefile.am @@ -0,0 +1,30 @@ +dmi_dir = $(lofar_sharedir)/../DMI + +SUBDIRS = . Glish + +CXXFLAGS += -Wall -Wno-unknown-pragmas -pg + +lib_LTLIBRARIES = liboctopussy.la + +liboctopussy_la_SOURCES = Dispatcher.cc Message.cc MsgAddress.cc \ + WPInterface.cc WorkProcess.cc Timestamp.cc OctopussyDebugContext.cc \ + GWClientWP.cc GWServerWP.cc GatewayWP.cc LoggerWP.cc \ + OctopussyConfig.cc \ + Net/Socket.cc Subscriptions.cc \ + AID-OCTOPUSSY-Registry.cc + +# script used to generate AID maps +MAPBUILDER = $(dmi_dir)/src/build_aid_maps.pl + +# All .aidlist files below this dir will be scanned +BASELISTDIR = $(lofar_sharedir)/.. + +# Your package's subdirectory +AID_DIR = $(top_srcdir)/src + +aids: + $(MAPBUILDER) `find $(BASELISTDIR) -name \*.aidlist` $(AID_DIR)/*.h $(AID_DIR)/Glish/*.h + + +include $(lofar_sharedir)/Makefile.common + diff --git a/CEP/CPA/OCTOPUSSY/src/Message.cc b/CEP/CPA/OCTOPUSSY/src/Message.cc new file mode 100755 index 0000000000000000000000000000000000000000..0f62bc65ef54579df2ab238d9ccf73ab606e9b07 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Message.cc @@ -0,0 +1,343 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7B7F2F024A.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7B7F2F024A.cm + +//## begin module%3C7B7F2F024A.cp preserve=no +//## end module%3C7B7F2F024A.cp + +//## Module: Message%3C7B7F2F024A; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Message.cc + +//## begin module%3C7B7F2F024A.additionalIncludes preserve=no +//## end module%3C7B7F2F024A.additionalIncludes + +//## begin module%3C7B7F2F024A.includes preserve=yes +#include "DMI/DynamicTypeManager.h" +//## end module%3C7B7F2F024A.includes + +// Message +#include "OCTOPUSSY/Message.h" +//## begin module%3C7B7F2F024A.declarations preserve=no +//## end module%3C7B7F2F024A.declarations + +//## begin module%3C7B7F2F024A.additionalDeclarations preserve=yes +//## end module%3C7B7F2F024A.additionalDeclarations + + +// Class Message + +Message::Message() + //## begin Message::Message%3C7B6A2D01F0_const.hasinit preserve=no + //## end Message::Message%3C7B6A2D01F0_const.hasinit + //## begin Message::Message%3C7B6A2D01F0_const.initialization preserve=yes + : hops_(0) + //## end Message::Message%3C7B6A2D01F0_const.initialization +{ + //## begin Message::Message%3C7B6A2D01F0_const.body preserve=yes + //## end Message::Message%3C7B6A2D01F0_const.body +} + +Message::Message(const Message &right) + //## begin Message::Message%3C7B6A2D01F0_copy.hasinit preserve=no + //## end Message::Message%3C7B6A2D01F0_copy.hasinit + //## begin Message::Message%3C7B6A2D01F0_copy.initialization preserve=yes + : BlockableObject() + //## end Message::Message%3C7B6A2D01F0_copy.initialization +{ + //## begin Message::Message%3C7B6A2D01F0_copy.body preserve=yes + (*this) = right; + //## end Message::Message%3C7B6A2D01F0_copy.body +} + +Message::Message (const HIID &id1, BlockableObject *pload, int flags, int pri) + //## begin Message::Message%3C7B9C490384.hasinit preserve=no + //## end Message::Message%3C7B9C490384.hasinit + //## begin Message::Message%3C7B9C490384.initialization preserve=yes + : priority_(pri),state_(0),hops_(0),id_(id1) + //## end Message::Message%3C7B9C490384.initialization +{ + //## begin Message::Message%3C7B9C490384.body preserve=yes + payload_.attach(pload,flags|DMI::PERSIST|DMI::WRITE); + //## end Message::Message%3C7B9C490384.body +} + +Message::Message (const HIID &id1, ObjRef &pload, int flags, int pri) + //## begin Message::Message%3C7B9D0A01FB.hasinit preserve=no + //## end Message::Message%3C7B9D0A01FB.hasinit + //## begin Message::Message%3C7B9D0A01FB.initialization preserve=yes + : priority_(pri),state_(0),hops_(0),id_(id1) + //## end Message::Message%3C7B9D0A01FB.initialization +{ + //## begin Message::Message%3C7B9D0A01FB.body preserve=yes + if( flags&DMI::COPYREF ) + payload_.copy(pload,flags|DMI::PERSIST|DMI::WRITE); + else + payload_.xfer(pload).persist(); + //## end Message::Message%3C7B9D0A01FB.body +} + +Message::Message (const HIID &id1, SmartBlock *bl, int flags, int pri) + //## begin Message::Message%3C7B9D3B02C3.hasinit preserve=no + //## end Message::Message%3C7B9D3B02C3.hasinit + //## begin Message::Message%3C7B9D3B02C3.initialization preserve=yes + : priority_(pri),state_(0),hops_(0),id_(id1) + //## end Message::Message%3C7B9D3B02C3.initialization +{ + //## begin Message::Message%3C7B9D3B02C3.body preserve=yes + block_.attach(bl,flags|DMI::PERSIST|DMI::WRITE); + //## end Message::Message%3C7B9D3B02C3.body +} + +Message::Message (const HIID &id1, BlockRef &bl, int flags, int pri) + //## begin Message::Message%3C7B9D59014A.hasinit preserve=no + //## end Message::Message%3C7B9D59014A.hasinit + //## begin Message::Message%3C7B9D59014A.initialization preserve=yes + : priority_(pri),state_(0),hops_(0),id_(id1) + //## end Message::Message%3C7B9D59014A.initialization +{ + //## begin Message::Message%3C7B9D59014A.body preserve=yes + if( flags&DMI::COPYREF ) + block_.copy(bl,flags|DMI::PERSIST|DMI::WRITE); + else + block_.xfer(bl).persist(); + //## end Message::Message%3C7B9D59014A.body +} + +Message::Message (const HIID &id1, const char *data, size_t sz, int pri) + //## begin Message::Message%3C7BB3BD0266.hasinit preserve=no + //## end Message::Message%3C7BB3BD0266.hasinit + //## begin Message::Message%3C7BB3BD0266.initialization preserve=yes + : priority_(pri),state_(0),hops_(0),id_(id1) + //## end Message::Message%3C7BB3BD0266.initialization +{ + //## begin Message::Message%3C7BB3BD0266.body preserve=yes + SmartBlock *bl = new SmartBlock(sz); + block_.attach( bl,DMI::ANON|DMI::WRITE|DMI::PERSIST); + memcpy(bl->data(),data,sz); + //## end Message::Message%3C7BB3BD0266.body +} + + +Message::~Message() +{ + //## begin Message::~Message%3C7B6A2D01F0_dest.body preserve=yes + //## end Message::~Message%3C7B6A2D01F0_dest.body +} + + +Message & Message::operator=(const Message &right) +{ + //## begin Message::operator=%3C7B6A2D01F0_assign.body preserve=yes + if( &right != this ) + { + id_ = right.id_; + priority_ = right.priority_; + from_ = right.from_; + to_ = right.to_; + state_ = right.state_; + // timestamp_ = right.timestamp_; + payload_.copy(right.payload_,DMI::PRESERVE_RW|DMI::PERSIST); + block_.copy(right.block_,DMI::PRESERVE_RW|DMI::PERSIST); + } + return *this; + //## end Message::operator=%3C7B6A2D01F0_assign.body +} + + + +//## Other Operations (implementation) +Message & Message::operator <<= (BlockableObject *pload) +{ + //## begin Message::operator <<=%3C7B9DDE0137.body preserve=yes + payload_.attach(pload,DMI::ANON|DMI::WRITE|DMI::PERSIST); + return *this; + //## end Message::operator <<=%3C7B9DDE0137.body +} + +Message & Message::operator <<= (ObjRef &pload) +{ + //## begin Message::operator <<=%3C7B9DF20014.body preserve=yes + payload_.xfer(pload).persist(); + return *this; + //## end Message::operator <<=%3C7B9DF20014.body +} + +Message & Message::operator <<= (SmartBlock *bl) +{ + //## begin Message::operator <<=%3C7B9E0A02AD.body preserve=yes + block_.attach(bl,DMI::ANON|DMI::WRITE|DMI::PERSIST); + return *this; + //## end Message::operator <<=%3C7B9E0A02AD.body +} + +Message & Message::operator <<= (BlockRef &bl) +{ + //## begin Message::operator <<=%3C7B9E1601CE.body preserve=yes + block_.xfer(bl).persist(); + return *this; + //## end Message::operator <<=%3C7B9E1601CE.body +} + +CountedRefTarget* Message::clone (int flags, int depth) const +{ + //## begin Message::clone%3C7E32BE01E0.body preserve=yes + Message *newmsg = new Message(*this); + newmsg->privatize(flags,depth); + return newmsg; + //## end Message::clone%3C7E32BE01E0.body +} + +void Message::privatize (int flags, int depth) +{ + //## begin Message::privatize%3C7E32C1022B.body preserve=yes + if( flags&DMI::DEEP || depth>0 ) + { + if( payload_.valid() ) + payload_.privatize(flags,depth-1); + if( block_.valid() ) + block_.privatize(flags,depth-1); + } + //## end Message::privatize%3C7E32C1022B.body +} + +NestableContainer::Hook Message::setBranch (const HIID &id, int flags) +{ + //## begin Message::setBranch%3CB42D0201B4.body preserve=yes + FailWhen( !payload_.valid() || !payload_->isNestable(),"payload is not a container" ); + // privatize payload if required (or if not writable) + if( flags&DMI::PRIVATIZE || + !payload_.isWritable() || + dynamic_cast<NestableContainer&>(payload_.dewr()).isWritable() ) + payload_.privatize(DMI::WRITE,0); + NestableContainer *nc = dynamic_cast<NestableContainer*>(payload_.dewr_p()); + Assert(nc); + return nc->setBranch(id,flags); + //## end Message::setBranch%3CB42D0201B4.body +} + +int Message::fromBlock (BlockSet& set) +{ + //## begin Message::fromBlock%3C960F1B0373.body preserve=yes + int blockcount = 1; + // get and unpack header + BlockRef href; + set.pop(href); + const HeaderBlock & hdr = *static_cast<const HeaderBlock*>(href->data()); + FailWhen(href->size() < sizeof(HeaderBlock) || + href->size() != sizeof(HeaderBlock) + + hdr.idsize + hdr.fromsize + hdr.tosize,"corrupt header block"); + priority_ = hdr.priority; + state_ = hdr.state; + hops_ = hdr.hops; + const char *buf = static_cast<const char*>(href->data()) + sizeof(HeaderBlock); + id_.unpack(buf,hdr.idsize); buf += hdr.idsize; + from_.unpack(buf,hdr.fromsize); buf += hdr.fromsize; + to_.unpack(buf,hdr.tosize); + // got a data block? + if( hdr.has_block ) + { + set.pop(block_); + blockcount++; + } + else + block_.detach(); + // got a payload? + if( hdr.payload_type ) + { + BlockableObject *obj = DynamicTypeManager::construct(hdr.payload_type); + blockcount += obj->fromBlock(set); + payload_.attach(obj,DMI::ANON|DMI::WRITE); + } + else + payload_.detach(); + + return blockcount; + //## end Message::fromBlock%3C960F1B0373.body +} + +int Message::toBlock (BlockSet &set) const +{ + //## begin Message::toBlock%3C960F20037A.body preserve=yes + // create a header block + size_t idsize = id_.packSize(), + tosize = to_.packSize(), + fromsize = from_.packSize(), + hsize = idsize+tosize+fromsize; + SmartBlock *hdrblock = new SmartBlock(sizeof(HeaderBlock)+hsize); + BlockRef bref(hdrblock,DMI::ANON|DMI::WRITE); + HeaderBlock & hdr = *static_cast<HeaderBlock*>(hdrblock->data()); + hdr.priority = priority_; + hdr.state = state_; + hdr.hops = hops_; + hdr.idsize = idsize; + hdr.fromsize = fromsize; + hdr.tosize = tosize; + hdr.has_block = block_.valid(); + hdr.payload_type = payload_.valid() ? payload_->objectType() : NullType; + char *buf = static_cast<char*>(hdrblock->data()) + sizeof(HeaderBlock); + buf += id_.pack(buf,hsize); + buf += from_.pack(buf,hsize); + to_.pack(buf,hsize); + + // attach to set + set.push(bref); + int blockcount = 1; + if( block_.valid() ) + { + set.pushNew().copy(block_,DMI::PRESERVE_RW); + blockcount++; + } + if( payload_.valid() ) + blockcount += payload_->toBlock(set); + return blockcount; + //## end Message::toBlock%3C960F20037A.body +} + +// Additional Declarations + //## begin Message%3C7B6A2D01F0.declarations preserve=yes +string Message::sdebug ( int detail,const string &prefix,const char *name ) const +{ + string out; + if( detail>=0 ) // basic detail + { + out = name?name:"Message"; + out += "/" + id_.toString(); + if( detail>3 ) + out += Debug::ssprintf("/%08x",this); + } + if( detail >= 1 || detail == -1 ) // normal detail + { + Debug::appendf(out,"%s->%s p:%d s:%x", + from_.toString().c_str(),to_.toString().c_str(),priority_,state_); + if( hops_ ) + Debug::appendf(out,"hc:%d",(int)hops_); + if( detail == 1 ) + { + Debug::appendf(out,payload_.valid() ? "w/payload" : "", + block_.valid() ? "w/block" : ""); + } + } + if( detail >=2 || detail <= -2) // high detail + { + if( out.length() ) + out += "\n"+prefix; + if( payload_.valid() ) + out += " payload: "+payload_.sdebug(abs(detail)-1,prefix+" "); + else + out += " no payload"; + if( block_.valid() ) + out += "\n"+prefix+" block: "+block_.sdebug(abs(detail)-1,prefix+" "); + else + out += " no block"; + } + return out; +} + //## end Message%3C7B6A2D01F0.declarations +//## begin module%3C7B7F2F024A.epilog preserve=yes +//## end module%3C7B7F2F024A.epilog diff --git a/CEP/CPA/OCTOPUSSY/src/Message.h b/CEP/CPA/OCTOPUSSY/src/Message.h new file mode 100755 index 0000000000000000000000000000000000000000..e8f61e7453dd6de6e622410635022d8d65425843 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Message.h @@ -0,0 +1,601 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7B7F2F0248.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7B7F2F0248.cm + +//## begin module%3C7B7F2F0248.cp preserve=no +//## end module%3C7B7F2F0248.cp + +//## Module: Message%3C7B7F2F0248; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Message.h + +#ifndef Message_h +#define Message_h 1 + +//## begin module%3C7B7F2F0248.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C7B7F2F0248.additionalIncludes + +//## begin module%3C7B7F2F0248.includes preserve=yes +#include "OCTOPUSSY/TID-OCTOPUSSY.h" +#include "DMI/DataRecord.h" +//## end module%3C7B7F2F0248.includes + +// CountedRef +#include "DMI/CountedRef.h" +// SmartBlock +#include "DMI/SmartBlock.h" +// NestableContainer +#include "DMI/NestableContainer.h" +// HIID +#include "DMI/HIID.h" +// BlockableObject +#include "DMI/BlockableObject.h" +// OctopussyDebugContext +#include "OCTOPUSSY/OctopussyDebugContext.h" +// MsgAddress +#include "OCTOPUSSY/MsgAddress.h" +//## begin module%3C7B7F2F0248.declarations preserve=no +//## end module%3C7B7F2F0248.declarations + +//## begin module%3C7B7F2F0248.additionalDeclarations preserve=yes +#pragma types #Message +#pragma aid Index + +#include "OCTOPUSSY/AID-OCTOPUSSY.h" +//## end module%3C7B7F2F0248.additionalDeclarations + + +//## begin Message%3C7B6A2D01F0.preface preserve=yes +class WPQueue; +//## end Message%3C7B6A2D01F0.preface + +//## Class: Message%3C7B6A2D01F0 +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +//## Uses: <unnamed>%3C7B70830385;MsgAddress { -> } +//## Uses: <unnamed>%3C7B708B00DD;HIID { -> } +//## Uses: <unnamed>%3C7E4D87012D;NestableContainer { -> } + +class Message : public OctopussyDebugContext, //## Inherits: <unnamed>%3C7FA31802FF + public BlockableObject //## Inherits: <unnamed>%3C960F080308 +{ + //## begin Message%3C7B6A2D01F0.initialDeclarations preserve=yes + public: + // some predefined priority levels + // a priority<0 is considered "none" + static const int PRI_LOWEST = 0, + PRI_LOWER = 0x10, + PRI_LOW = 0x20, + PRI_NORMAL = 0x100, + PRI_HIGH = 0x200, + PRI_HIGHER = 0x400, + PRI_EVENT = 0x800; + + // message delivery/subscription scope + typedef enum { + GLOBAL = 2, + HOST = 1, + PROCESS = 0, + LOCAL = 0 + } MessageScope; + + // message processing results (returned by WPInterface::receive(), etc.) + typedef enum { + ACCEPT = 0, // message processed, OK to remove from queue + HOLD = 1, // hold the message (and block queue) until something else happens + REQUEUE = 2, // requeue the message and try again + CANCEL = 3 // for input()/timeout()/signal(), cancel the input or timeout + } MessageResults; + + //## end Message%3C7B6A2D01F0.initialDeclarations + + public: + //## Constructors (generated) + Message(); + + Message(const Message &right); + + //## Constructors (specified) + //## Operation: Message%3C8CB2CE00DC + explicit Message (const HIID &id1, int pri = PRI_NORMAL); + + //## Operation: Message%3C7B9C490384 + Message (const HIID &id1, BlockableObject *pload, int flags = 0, int pri = PRI_NORMAL); + + //## Operation: Message%3C7B9D0A01FB + Message (const HIID &id1, ObjRef &pload, int flags = 0, int pri = PRI_NORMAL); + + //## Operation: Message%3C7B9D3B02C3 + Message (const HIID &id1, SmartBlock *bl, int flags = 0, int pri = PRI_NORMAL); + + //## Operation: Message%3C7B9D59014A + Message (const HIID &id1, BlockRef &bl, int flags = 0, int pri = PRI_NORMAL); + + //## Operation: Message%3C7BB3BD0266 + Message (const HIID &id1, const char *data, size_t sz, int pri = PRI_NORMAL); + + //## Destructor (generated) + ~Message(); + + //## Assignment Operation (generated) + Message & operator=(const Message &right); + + + //## Other Operations (specified) + //## Operation: operator <<=%3C7B9DDE0137 + Message & operator <<= (BlockableObject *pload); + + //## Operation: operator <<=%3C7B9DF20014 + Message & operator <<= (ObjRef &pload); + + //## Operation: operator <<=%3C7B9E0A02AD + Message & operator <<= (SmartBlock *bl); + + //## Operation: operator <<=%3C7B9E1601CE + Message & operator <<= (BlockRef &bl); + + //## Operation: clone%3C7E32BE01E0; C++ + // Abstract method for cloning an object. Should return pointer to new + // object. Flags: DMI::WRITE if writable clone is required, DMI::DEEP + // for deep cloning (i.e. contents of object will be cloned as well). + virtual CountedRefTarget* clone (int flags = 0, int depth = 0) const; + + //## Operation: privatize%3C7E32C1022B + // Virtual method for privatization of an object. If the object + // contains other refs, they should be privatized by this method. The + // DMI::DEEP flag should be passed on to child refs, for deep + // privatization. + virtual void privatize (int flags = 0, int depth = 0); + + //## Operation: operator []%3C7F56ED007D + NestableContainer::Hook operator [] (const HIID &id); + + //## Operation: operator []%3C7E4C310348 + NestableContainer::Hook operator [] (int n); + + //## Operation: operator []%3C7E4C3E003A + NestableContainer::ConstHook operator [] (const HIID &id) const; + + //## Operation: operator []%3C7F56D90197 + NestableContainer::ConstHook operator [] (int n) const; + + //## Operation: setBranch%3CB42D0201B4 + NestableContainer::Hook setBranch (const HIID &id, int flags = DMI::WRITE); + + //## Operation: data%3C7E443A016A + void * data (); + + //## Operation: data%3C7E446B02B5 + const void * data () const; + + //## Operation: datasize%3C7E443E01B6 + size_t datasize () const; + + //## Operation: objectType%3C960F16009B + // Returns the class TypeId + virtual TypeId objectType () const; + + //## Operation: fromBlock%3C960F1B0373 + // Creates object from a set of block references. Appropriate number of + // references are removed from the head of the BlockSet. Returns # of + // refs removed. + virtual int fromBlock (BlockSet& set); + + //## Operation: toBlock%3C960F20037A + // Stores an object into a set of blocks. Appropriate number of refs + // added to tail of BlockSet. Returns # of block refs added. + virtual int toBlock (BlockSet &set) const; + + //## Get and Set Operations for Class Attributes (generated) + + //## Attribute: priority%3C7B94970023 + int priority () const; + void setPriority (int value); + + //## Attribute: state%3C7E33F40330 + int state () const; + void setState (int value); + + //## Attribute: hops%3CC952D7039B + short hops () const; + void setHops (short value); + + //## Get and Set Operations for Associations (generated) + + //## Association: OCTOPUSSY::<unnamed>%3C7B70FF033D + //## Role: Message::to%3C7B7100015E + const MsgAddress& to () const; + void setTo (const MsgAddress& value); + + //## Association: OCTOPUSSY::<unnamed>%3C7B71050151 + //## Role: Message::from%3C7B7106029D + const MsgAddress& from () const; + void setFrom (const MsgAddress& value); + + //## Association: OCTOPUSSY::<unnamed>%3C7B71820219 + //## Role: Message::id%3C7B718500FB + const HIID& id () const; + void setId (const HIID& value); + + //## Association: OCTOPUSSY::<unnamed>%3C7B9796024D + //## Role: Message::payload%3C7B97970096 + const ObjRef& payload () const; + + //## Association: OCTOPUSSY::<unnamed>%3C7B9799014D + //## Role: Message::block%3C7B97990388 + const BlockRef& block () const; + + //## Association: OCTOPUSSY::<unnamed>%3CC9530802FB + //## Role: Message::forwarder%3CC9530903D9 + const MsgAddress& forwarder () const; + void setForwarder (const MsgAddress& value); + + // Additional Public Declarations + //## begin Message%3C7B6A2D01F0.public preserve=yes + ObjRef& payload (); + BlockRef& block (); + + short addHop (); + + // explicit versions of [] for string IDs + NestableContainer::ConstHook operator [] (AtomicID id1) const + { return (*this)[HIID(id1)]; } + NestableContainer::ConstHook operator [] (const string &id1) const + { return (*this)[HIID(id1)]; } + NestableContainer::ConstHook operator [] (const char *id1) const + { return (*this)[HIID(id1)]; } + NestableContainer::Hook operator [] (AtomicID id1) + { return (*this)[HIID(id1)]; } + NestableContainer::Hook operator [] (const string &id1) + { return (*this)[HIID(id1)]; } + NestableContainer::Hook operator [] (const char *id1) + { return (*this)[HIID(id1)]; } + + typedef CountedRef<Message> Ref; + +// typedef struct { +// WPQueue *wpq; +// int handle; +// HIID id; +// void *data; +// } TimeoutData; + + // This is a typical debug() method setup. The sdebug() + // method creates a debug info string at the given level of detail. + string sdebug ( int detail = 1,const string &prefix = "", + const char *name = 0 ) const; + const char * debug ( int detail = 1,const string &prefix = "", + const char *name = 0 ) const + { return Debug::staticBuffer(sdebug(detail,prefix,name)); } + + //## end Message%3C7B6A2D01F0.public + protected: + // Additional Protected Declarations + //## begin Message%3C7B6A2D01F0.protected preserve=yes + BlockSet payload_set; + typedef struct { + size_t idsize; + int priority; + int state; + char to[MsgAddress::byte_size], + from[MsgAddress::byte_size]; + int num_payload_blocks; + size_t block_size; + } MessageBlock; + //## end Message%3C7B6A2D01F0.protected + private: + // Additional Private Declarations + //## begin Message%3C7B6A2D01F0.private preserve=yes + //## end Message%3C7B6A2D01F0.private + + private: //## implementation + // Data Members for Class Attributes + + //## begin Message::priority%3C7B94970023.attr preserve=no public: int {U} + int priority_; + //## end Message::priority%3C7B94970023.attr + + //## begin Message::state%3C7E33F40330.attr preserve=no public: int {U} + int state_; + //## end Message::state%3C7E33F40330.attr + + //## begin Message::hops%3CC952D7039B.attr preserve=no public: short {U} + short hops_; + //## end Message::hops%3CC952D7039B.attr + + // Data Members for Associations + + //## Association: OCTOPUSSY::<unnamed>%3C7B70FF033D + //## begin Message::to%3C7B7100015E.role preserve=no public: MsgAddress { -> 1VHgN} + MsgAddress to_; + //## end Message::to%3C7B7100015E.role + + //## Association: OCTOPUSSY::<unnamed>%3C7B71050151 + //## begin Message::from%3C7B7106029D.role preserve=no public: MsgAddress { -> 1VHgN} + MsgAddress from_; + //## end Message::from%3C7B7106029D.role + + //## Association: OCTOPUSSY::<unnamed>%3C7B71820219 + //## begin Message::id%3C7B718500FB.role preserve=no public: HIID { -> 1VHgN} + HIID id_; + //## end Message::id%3C7B718500FB.role + + //## Association: OCTOPUSSY::<unnamed>%3C7B9796024D + //## begin Message::payload%3C7B97970096.role preserve=no public: BlockableObject { -> 0..1RHgN} + ObjRef payload_; + //## end Message::payload%3C7B97970096.role + + //## Association: OCTOPUSSY::<unnamed>%3C7B9799014D + //## begin Message::block%3C7B97990388.role preserve=no public: SmartBlock { -> 0..1RHgN} + BlockRef block_; + //## end Message::block%3C7B97990388.role + + //## Association: OCTOPUSSY::<unnamed>%3CC9530802FB + //## begin Message::forwarder%3CC9530903D9.role preserve=no public: MsgAddress { -> 1VHgN} + MsgAddress forwarder_; + //## end Message::forwarder%3CC9530903D9.role + + // Additional Implementation Declarations + //## begin Message%3C7B6A2D01F0.implementation preserve=yes + typedef struct { int priority,state,idsize,fromsize,tosize; + short hops; + bool has_block; + TypeId payload_type; + } HeaderBlock; + + //## end Message%3C7B6A2D01F0.implementation +}; + +//## begin Message%3C7B6A2D01F0.postscript preserve=yes +//## end Message%3C7B6A2D01F0.postscript + +//## begin MessageRef%3C7B722600DE.preface preserve=yes +//## end MessageRef%3C7B722600DE.preface + +//## Class: MessageRef%3C7B722600DE +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +//## Uses: <unnamed>%3C7B7262018F;CountedRef { -> } +//## Uses: <unnamed>%3C7B726503E2;Message { -> } + +typedef Message::Ref MessageRef; +//## begin MessageRef%3C7B722600DE.postscript preserve=yes +//## end MessageRef%3C7B722600DE.postscript + +// Class Message + +inline Message::Message (const HIID &id1, int pri) + //## begin Message::Message%3C8CB2CE00DC.hasinit preserve=no + //## end Message::Message%3C8CB2CE00DC.hasinit + //## begin Message::Message%3C8CB2CE00DC.initialization preserve=yes + : priority_(pri),state_(0),hops_(0),id_(id1) + //## end Message::Message%3C8CB2CE00DC.initialization +{ + //## begin Message::Message%3C8CB2CE00DC.body preserve=yes + //## end Message::Message%3C8CB2CE00DC.body +} + + + +//## Other Operations (inline) +inline NestableContainer::Hook Message::operator [] (const HIID &id) +{ + //## begin Message::operator []%3C7F56ED007D.body preserve=yes + if( payload_.valid() ) + { FailWhen( !payload_->isNestable(),"payload is not a container" ); } + else + payload_.attach(new DataRecord,DMI::ANON|DMI::WRITE|DMI::PERSIST); + return (*static_cast<NestableContainer*>( + const_cast<BlockableObject*>(&payload_.deref())))[id]; + //## end Message::operator []%3C7F56ED007D.body +} + +inline NestableContainer::Hook Message::operator [] (int n) +{ + //## begin Message::operator []%3C7E4C310348.body preserve=yes + if( payload_.valid() ) + { FailWhen( !payload_->isNestable(),"payload is not a container" ); } + else + payload_.attach(new DataRecord,DMI::ANON|DMI::WRITE|DMI::PERSIST); + + return (*static_cast<NestableContainer*>( + const_cast<BlockableObject*>(&payload_.deref())))[n]; + //## end Message::operator []%3C7E4C310348.body +} + +inline NestableContainer::ConstHook Message::operator [] (const HIID &id) const +{ + //## begin Message::operator []%3C7E4C3E003A.body preserve=yes + FailWhen( !payload_.valid() || !payload_->isNestable(),"payload is not a container" ); + return (*static_cast<const NestableContainer*>(&payload_.deref()))[id]; + //## end Message::operator []%3C7E4C3E003A.body +} + +inline NestableContainer::ConstHook Message::operator [] (int n) const +{ + //## begin Message::operator []%3C7F56D90197.body preserve=yes + FailWhen( !payload_.valid() || !payload_->isNestable(),"payload is not a container" ); + return (*static_cast<const NestableContainer*>(&payload_.deref()))[n]; + //## end Message::operator []%3C7F56D90197.body +} + +inline void * Message::data () +{ + //## begin Message::data%3C7E443A016A.body preserve=yes + return block_.valid() ? block_().data() : 0; + //## end Message::data%3C7E443A016A.body +} + +inline const void * Message::data () const +{ + //## begin Message::data%3C7E446B02B5.body preserve=yes + return block_.valid() ? block_->data() : 0; + //## end Message::data%3C7E446B02B5.body +} + +inline size_t Message::datasize () const +{ + //## begin Message::datasize%3C7E443E01B6.body preserve=yes + return block_.valid() ? block_->size() : 0; + //## end Message::datasize%3C7E443E01B6.body +} + +inline TypeId Message::objectType () const +{ + //## begin Message::objectType%3C960F16009B.body preserve=yes + return TpMessage; + //## end Message::objectType%3C960F16009B.body +} + +//## Get and Set Operations for Class Attributes (inline) + +inline int Message::priority () const +{ + //## begin Message::priority%3C7B94970023.get preserve=no + return priority_; + //## end Message::priority%3C7B94970023.get +} + +inline void Message::setPriority (int value) +{ + //## begin Message::setPriority%3C7B94970023.set preserve=no + priority_ = value; + //## end Message::setPriority%3C7B94970023.set +} + +inline int Message::state () const +{ + //## begin Message::state%3C7E33F40330.get preserve=no + return state_; + //## end Message::state%3C7E33F40330.get +} + +inline void Message::setState (int value) +{ + //## begin Message::setState%3C7E33F40330.set preserve=no + state_ = value; + //## end Message::setState%3C7E33F40330.set +} + +inline short Message::hops () const +{ + //## begin Message::hops%3CC952D7039B.get preserve=no + return hops_; + //## end Message::hops%3CC952D7039B.get +} + +inline void Message::setHops (short value) +{ + //## begin Message::setHops%3CC952D7039B.set preserve=no + hops_ = value; + //## end Message::setHops%3CC952D7039B.set +} + +//## Get and Set Operations for Associations (inline) + +inline const MsgAddress& Message::to () const +{ + //## begin Message::to%3C7B7100015E.get preserve=no + return to_; + //## end Message::to%3C7B7100015E.get +} + +inline void Message::setTo (const MsgAddress& value) +{ + //## begin Message::setTo%3C7B7100015E.set preserve=no + to_ = value; + //## end Message::setTo%3C7B7100015E.set +} + +inline const MsgAddress& Message::from () const +{ + //## begin Message::from%3C7B7106029D.get preserve=no + return from_; + //## end Message::from%3C7B7106029D.get +} + +inline void Message::setFrom (const MsgAddress& value) +{ + //## begin Message::setFrom%3C7B7106029D.set preserve=no + from_ = value; + //## end Message::setFrom%3C7B7106029D.set +} + +inline const HIID& Message::id () const +{ + //## begin Message::id%3C7B718500FB.get preserve=no + return id_; + //## end Message::id%3C7B718500FB.get +} + +inline void Message::setId (const HIID& value) +{ + //## begin Message::setId%3C7B718500FB.set preserve=no + id_ = value; + //## end Message::setId%3C7B718500FB.set +} + +inline const ObjRef& Message::payload () const +{ + //## begin Message::payload%3C7B97970096.get preserve=no + return payload_; + //## end Message::payload%3C7B97970096.get +} + +inline const BlockRef& Message::block () const +{ + //## begin Message::block%3C7B97990388.get preserve=no + return block_; + //## end Message::block%3C7B97990388.get +} + +inline const MsgAddress& Message::forwarder () const +{ + //## begin Message::forwarder%3CC9530903D9.get preserve=no + return forwarder_; + //## end Message::forwarder%3CC9530903D9.get +} + +inline void Message::setForwarder (const MsgAddress& value) +{ + //## begin Message::setForwarder%3CC9530903D9.set preserve=no + forwarder_ = value; + //## end Message::setForwarder%3CC9530903D9.set +} + +//## begin module%3C7B7F2F0248.epilog preserve=yes +inline ObjRef& Message::payload () +{ + return payload_; +} + +inline BlockRef& Message::block () +{ + return block_; +} + +inline short Message::addHop () +{ + return ++hops_; +} +//## end module%3C7B7F2F0248.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/MsgAddress.cc b/CEP/CPA/OCTOPUSSY/src/MsgAddress.cc new file mode 100755 index 0000000000000000000000000000000000000000..d6c06e495cc75afdd24a520cb646ce76f2f25b70 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/MsgAddress.cc @@ -0,0 +1,73 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7B7F2F0380.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7B7F2F0380.cm + +//## begin module%3C7B7F2F0380.cp preserve=no +//## end module%3C7B7F2F0380.cp + +//## Module: MsgAddress%3C7B7F2F0380; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\MsgAddress.cc + +//## begin module%3C7B7F2F0380.additionalIncludes preserve=no +//## end module%3C7B7F2F0380.additionalIncludes + +//## begin module%3C7B7F2F0380.includes preserve=yes +//## end module%3C7B7F2F0380.includes + +// MsgAddress +#include "OCTOPUSSY/MsgAddress.h" +//## begin module%3C7B7F2F0380.declarations preserve=no +//## end module%3C7B7F2F0380.declarations + +//## begin module%3C7B7F2F0380.additionalDeclarations preserve=yes +//## end module%3C7B7F2F0380.additionalDeclarations + + +// Class MsgAddress + +// Additional Declarations + //## begin MsgAddress%3C7B6F790197.declarations preserve=yes + //## end MsgAddress%3C7B6F790197.declarations + +// Class WPID + +// Additional Declarations + //## begin WPID%3C8F9A340206.declarations preserve=yes + //## end WPID%3C8F9A340206.declarations + +//## begin module%3C7B7F2F0380.epilog preserve=yes +//## end module%3C7B7F2F0380.epilog + + +// Detached code regions: +#if 0 +//## begin MsgAddress::MsgAddress%3C7B6F790197_copy.initialization preserve=yes + : HIID(right) +//## end MsgAddress::MsgAddress%3C7B6F790197_copy.initialization + +//## begin MsgAddress::operator=%3C7B6F790197_assign.body preserve=yes + *static_cast<HIID*>(this) = static_cast<const HIID&>(right); + return *this; +//## end MsgAddress::operator=%3C7B6F790197_assign.body + +//## begin MsgAddress::MsgAddress%3C7B6FAE00FD.initialization preserve=yes + : HIID(3) +//## end MsgAddress::MsgAddress%3C7B6FAE00FD.initialization + +//## begin MsgAddress::MsgAddress%3C7B6FAE00FD.body preserve=yes + (*this)[0] = host; + (*this)[1] = proc; + (*this)[2] = wp; +//## end MsgAddress::MsgAddress%3C7B6FAE00FD.body + +//## begin MsgAddress::wp%3C7B6FED02B7.body preserve=yes + return (*this)[2]; +//## end MsgAddress::wp%3C7B6FED02B7.body + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/MsgAddress.h b/CEP/CPA/OCTOPUSSY/src/MsgAddress.h new file mode 100755 index 0000000000000000000000000000000000000000..c85887c7dcb90aa3320d68d72e818e417cfa3554 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/MsgAddress.h @@ -0,0 +1,289 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7B7F2F037E.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7B7F2F037E.cm + +//## begin module%3C7B7F2F037E.cp preserve=no +//## end module%3C7B7F2F037E.cp + +//## Module: MsgAddress%3C7B7F2F037E; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\MsgAddress.h + +#ifndef MsgAddress_h +#define MsgAddress_h 1 + +//## begin module%3C7B7F2F037E.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C7B7F2F037E.additionalIncludes + +//## begin module%3C7B7F2F037E.includes preserve=yes +#include "OCTOPUSSY/AID-OCTOPUSSY.h" +//## end module%3C7B7F2F037E.includes + +// HIID +#include "DMI/HIID.h" +//## begin module%3C7B7F2F037E.declarations preserve=no +//## end module%3C7B7F2F037E.declarations + +//## begin module%3C7B7F2F037E.additionalDeclarations preserve=yes +#pragma aidgroup OCTOPUSSY +#pragma aid Dispatcher Local Publish +//## end module%3C7B7F2F037E.additionalDeclarations + + +//## begin WPID%3C8F9A340206.preface preserve=yes +//## end WPID%3C8F9A340206.preface + +//## Class: WPID%3C8F9A340206 +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +class WPID : public HIID //## Inherits: <unnamed>%3C8F9A5B0343 +{ + //## begin WPID%3C8F9A340206.initialDeclarations preserve=yes + //## end WPID%3C8F9A340206.initialDeclarations + + public: + //## Constructors (generated) + WPID(); + + //## Constructors (specified) + //## Operation: WPID%3C8F9AC70027 + WPID (AtomicID wpc, AtomicID inst = 0); + + + //## Other Operations (specified) + //## Operation: wpclass%3C8F9AA503C1 + AtomicID wpclass () const; + + //## Operation: inst%3C8F9AAB0103 + AtomicID inst () const; + + // Additional Public Declarations + //## begin WPID%3C8F9A340206.public preserve=yes + static const size_t byte_size = 2*sizeof(int); + //## end WPID%3C8F9A340206.public + protected: + // Additional Protected Declarations + //## begin WPID%3C8F9A340206.protected preserve=yes + //## end WPID%3C8F9A340206.protected + + private: + // Additional Private Declarations + //## begin WPID%3C8F9A340206.private preserve=yes + //## end WPID%3C8F9A340206.private + + private: //## implementation + // Additional Implementation Declarations + //## begin WPID%3C8F9A340206.implementation preserve=yes + //## end WPID%3C8F9A340206.implementation + +}; + +//## begin WPID%3C8F9A340206.postscript preserve=yes +//## end WPID%3C8F9A340206.postscript + +//## begin MsgAddress%3C7B6F790197.preface preserve=yes +//## end MsgAddress%3C7B6F790197.preface + +//## Class: MsgAddress%3C7B6F790197 +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +class MsgAddress : public WPID //## Inherits: <unnamed>%3C8F9A8F0199 +{ + //## begin MsgAddress%3C7B6F790197.initialDeclarations preserve=yes + //## end MsgAddress%3C7B6F790197.initialDeclarations + + public: + //## Constructors (generated) + MsgAddress(); + + //## Constructors (specified) + //## Operation: MsgAddress%3C7B6FAE00FD + MsgAddress (AtomicID wpc, AtomicID wpinst = 0, AtomicID proc = AidLocal, AtomicID host = AidLocal); + + //## Operation: MsgAddress%3C8F9B8E0087 + MsgAddress (const WPID& wpid, AtomicID proc = AidLocal, AtomicID host = AidLocal); + + + //## Other Operations (specified) + //## Operation: wpid%3C8F9BC10135 + WPID wpid () const; + + //## Operation: process%3C7B6FF7033D + AtomicID & process (); + + //## Operation: process%3C90700001B4 + const AtomicID & process () const; + + //## Operation: host%3C7B6FFC0330 + AtomicID & host (); + + //## Operation: host%3C9070080170 + const AtomicID & host () const; + + // Additional Public Declarations + //## begin MsgAddress%3C7B6F790197.public preserve=yes + HIID peerid () const + { return process()|host(); } + + static const size_t byte_size = 4*sizeof(int); + //## end MsgAddress%3C7B6F790197.public + protected: + // Additional Protected Declarations + //## begin MsgAddress%3C7B6F790197.protected preserve=yes + //## end MsgAddress%3C7B6F790197.protected + + private: + // Additional Private Declarations + //## begin MsgAddress%3C7B6F790197.private preserve=yes + //## end MsgAddress%3C7B6F790197.private + + private: //## implementation + // Additional Implementation Declarations + //## begin MsgAddress%3C7B6F790197.implementation preserve=yes + //## end MsgAddress%3C7B6F790197.implementation + +}; + +//## begin MsgAddress%3C7B6F790197.postscript preserve=yes +//## end MsgAddress%3C7B6F790197.postscript + +// Class WPID + +inline WPID::WPID() + //## begin WPID::WPID%3C8F9A340206_const.hasinit preserve=no + //## end WPID::WPID%3C8F9A340206_const.hasinit + //## begin WPID::WPID%3C8F9A340206_const.initialization preserve=yes + //## end WPID::WPID%3C8F9A340206_const.initialization +{ + //## begin WPID::WPID%3C8F9A340206_const.body preserve=yes + //## end WPID::WPID%3C8F9A340206_const.body +} + +inline WPID::WPID (AtomicID wpc, AtomicID inst) + //## begin WPID::WPID%3C8F9AC70027.hasinit preserve=no + //## end WPID::WPID%3C8F9AC70027.hasinit + //## begin WPID::WPID%3C8F9AC70027.initialization preserve=yes + : HIID(wpc) + //## end WPID::WPID%3C8F9AC70027.initialization +{ + //## begin WPID::WPID%3C8F9AC70027.body preserve=yes + add(inst); + //## end WPID::WPID%3C8F9AC70027.body +} + + + +//## Other Operations (inline) +inline AtomicID WPID::wpclass () const +{ + //## begin WPID::wpclass%3C8F9AA503C1.body preserve=yes + return (*this)[0]; + //## end WPID::wpclass%3C8F9AA503C1.body +} + +inline AtomicID WPID::inst () const +{ + //## begin WPID::inst%3C8F9AAB0103.body preserve=yes + return (*this)[1]; + //## end WPID::inst%3C8F9AAB0103.body +} + +// Class MsgAddress + +inline MsgAddress::MsgAddress() + //## begin MsgAddress::MsgAddress%3C7B6F790197_const.hasinit preserve=no + //## end MsgAddress::MsgAddress%3C7B6F790197_const.hasinit + //## begin MsgAddress::MsgAddress%3C7B6F790197_const.initialization preserve=yes + //## end MsgAddress::MsgAddress%3C7B6F790197_const.initialization +{ + //## begin MsgAddress::MsgAddress%3C7B6F790197_const.body preserve=yes + resize(4); + //## end MsgAddress::MsgAddress%3C7B6F790197_const.body +} + +inline MsgAddress::MsgAddress (AtomicID wpc, AtomicID wpinst, AtomicID proc, AtomicID host) + //## begin MsgAddress::MsgAddress%3C7B6FAE00FD.hasinit preserve=no + //## end MsgAddress::MsgAddress%3C7B6FAE00FD.hasinit + //## begin MsgAddress::MsgAddress%3C7B6FAE00FD.initialization preserve=yes + : WPID(wpc,wpinst) + //## end MsgAddress::MsgAddress%3C7B6FAE00FD.initialization +{ + //## begin MsgAddress::MsgAddress%3C7B6FAE00FD.body preserve=yes + add(proc); + add(host); + //## end MsgAddress::MsgAddress%3C7B6FAE00FD.body +} + +inline MsgAddress::MsgAddress (const WPID& wpid, AtomicID proc, AtomicID host) + //## begin MsgAddress::MsgAddress%3C8F9B8E0087.hasinit preserve=no + //## end MsgAddress::MsgAddress%3C8F9B8E0087.hasinit + //## begin MsgAddress::MsgAddress%3C8F9B8E0087.initialization preserve=yes + : WPID(wpid) + //## end MsgAddress::MsgAddress%3C8F9B8E0087.initialization +{ + //## begin MsgAddress::MsgAddress%3C8F9B8E0087.body preserve=yes + add(proc); + add(host); + //## end MsgAddress::MsgAddress%3C8F9B8E0087.body +} + + + +//## Other Operations (inline) +inline WPID MsgAddress::wpid () const +{ + //## begin MsgAddress::wpid%3C8F9BC10135.body preserve=yes + return WPID(wpclass(),inst()); + //## end MsgAddress::wpid%3C8F9BC10135.body +} + +inline AtomicID & MsgAddress::process () +{ + //## begin MsgAddress::process%3C7B6FF7033D.body preserve=yes + return (*this)[2]; + //## end MsgAddress::process%3C7B6FF7033D.body +} + +inline const AtomicID & MsgAddress::process () const +{ + //## begin MsgAddress::process%3C90700001B4.body preserve=yes + return (*this)[2]; + //## end MsgAddress::process%3C90700001B4.body +} + +inline AtomicID & MsgAddress::host () +{ + //## begin MsgAddress::host%3C7B6FFC0330.body preserve=yes + return (*this)[3]; + //## end MsgAddress::host%3C7B6FFC0330.body +} + +inline const AtomicID & MsgAddress::host () const +{ + //## begin MsgAddress::host%3C9070080170.body preserve=yes + return (*this)[3]; + //## end MsgAddress::host%3C9070080170.body +} + +//## begin module%3C7B7F2F037E.epilog preserve=yes +//## end module%3C7B7F2F037E.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/Net/Socket.cc b/CEP/CPA/OCTOPUSSY/src/Net/Socket.cc new file mode 100755 index 0000000000000000000000000000000000000000..6bc1e633b172d86be4767d91196ac4f1108636f3 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Net/Socket.cc @@ -0,0 +1,707 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C90D43B0096.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C90D43B0096.cm + +//## begin module%3C90D43B0096.cp preserve=no +//## end module%3C90D43B0096.cp + +//## Module: Socket%3C90D43B0096; Package body +//## Subsystem: OCTOPUSSY::Net%3C90D442031F +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Net\Socket.cc + +//## begin module%3C90D43B0096.additionalIncludes preserve=no +//## end module%3C90D43B0096.additionalIncludes + +//## begin module%3C90D43B0096.includes preserve=yes +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <unistd.h> +#include <string.h> +#include <signal.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include "OCTOPUSSY/OctopussyDebugContext.h" +//## end module%3C90D43B0096.includes + +// Socket +#include "OCTOPUSSY/Net/Socket.h" +//## begin module%3C90D43B0096.declarations preserve=no +//## end module%3C90D43B0096.declarations + +//## begin module%3C90D43B0096.additionalDeclarations preserve=yes +InitDebugSubContext(Socket,OctopussyDebugContext,"Socket"); +//## end module%3C90D43B0096.additionalDeclarations + + +// Class Socket + +Socket::Socket (const string &sname) + //## begin Socket::Socket%3C91BA4300F6.hasinit preserve=no + //## end Socket::Socket%3C91BA4300F6.hasinit + //## begin Socket::Socket%3C91BA4300F6.initialization preserve=yes + : name(sname),errcode_(Socket::NOINIT),sid(-1),bound(False) + //## end Socket::Socket%3C91BA4300F6.initialization +{ + //## begin Socket::Socket%3C91BA4300F6.body preserve=yes + //## end Socket::Socket%3C91BA4300F6.body +} + +Socket::Socket (const string &sname, const string &serv, int proto, int backlog) + //## begin Socket::Socket%9FD2BC39FEED.hasinit preserve=no + //## end Socket::Socket%9FD2BC39FEED.hasinit + //## begin Socket::Socket%9FD2BC39FEED.initialization preserve=yes + : name(sname),port_(serv),bound(False) + //## end Socket::Socket%9FD2BC39FEED.initialization +{ + //## begin Socket::Socket%9FD2BC39FEED.body preserve=yes + initServer(serv,proto,backlog); + //## end Socket::Socket%9FD2BC39FEED.body +} + +Socket::Socket (const string &sname, const string &host, const string &serv, int proto, int wait_ms) + //## begin Socket::Socket%C15CE2A5FEED.hasinit preserve=no + //## end Socket::Socket%C15CE2A5FEED.hasinit + //## begin Socket::Socket%C15CE2A5FEED.initialization preserve=yes + : name(sname),host_(host),port_(serv),bound(False) + //## end Socket::Socket%C15CE2A5FEED.initialization +{ + //## begin Socket::Socket%C15CE2A5FEED.body preserve=yes + initClient(host,serv,proto,wait_ms); + //## end Socket::Socket%C15CE2A5FEED.body +} + +Socket::Socket (int id, struct sockaddr_in &sa) + //## begin Socket::Socket%4760B82BFEED.hasinit preserve=no + //## end Socket::Socket%4760B82BFEED.hasinit + //## begin Socket::Socket%4760B82BFEED.initialization preserve=yes + : name("client"),sid(id),type(TCP),host_(">tcp"),port_("0"),bound(False) + //## end Socket::Socket%4760B82BFEED.initialization +{ + //## begin Socket::Socket%4760B82BFEED.body preserve=yes + dprintf(1)("creating connected socket\n"); + // constructs a generic socket (used by accept(), below) + rmt_addr = sa; + if( setDefaults()<0 ) + { + close(sid); + sid = -1; + return; + } +// Set non-blocking mode + if( fcntl(sid,F_SETFL,FNDELAY)<0 ) + set_errcode(SOCKOPT); + //## end Socket::Socket%4760B82BFEED.body +} + +Socket::Socket (int id, struct sockaddr_un &sa) + //## begin Socket::Socket%3CC95D6E032A.hasinit preserve=no + //## end Socket::Socket%3CC95D6E032A.hasinit + //## begin Socket::Socket%3CC95D6E032A.initialization preserve=yes + : name("client"),sid(id),type(UNIX),host_(">unix"),port_("0"),bound(False) + //## end Socket::Socket%3CC95D6E032A.initialization +{ + //## begin Socket::Socket%3CC95D6E032A.body preserve=yes + dprintf(1)("creating connected socket\n"); + unix_addr = sa; + if( setDefaults()<0 ) + { + close(sid); + sid = -1; + return; + } +// Set non-blocking mode + if( fcntl(sid,F_SETFL,FNDELAY)<0 ) + set_errcode(SOCKOPT); + //## end Socket::Socket%3CC95D6E032A.body +} + + +Socket::~Socket() +{ + //## begin Socket::~Socket%3C90CE58024E_dest.body preserve=yes + if( sid >=0 ) + { + dprintf(1)("close(fd)\n"); + close(sid); + } + if( bound && type == Socket::UNIX && unix_addr.sun_path[0] ) + { + int res = unlink(unix_addr.sun_path); + dprintf(1)("unlink(%s) = %d (%s)\n",unix_addr.sun_path,res<0?errno:res,res<0?strerror(errno):"OK"); + } + dprintf(1)("destroying socket\n"); + //## end Socket::~Socket%3C90CE58024E_dest.body +} + + + +//## Other Operations (implementation) +int Socket::initServer (const string &serv, int proto, int backlog) +{ + //## begin Socket::initServer%3C91B9FC0130.body preserve=yes + // open a server socket + errcode_ = errno_sys_ = 0; + sid = -1; + server = True; + connected = bound = False; + type = proto; + + if( type == UNIX ) + { + host_ = "unix"; + port_ = serv; + // setup socket address + unix_addr.sun_family = AF_UNIX; + FailWhen( serv.length() >= sizeof(unix_addr.sun_path),"socket name too long"); + if( serv[0] == '=' ) // abstract socket name + { + memset(unix_addr.sun_path,0,sizeof(unix_addr.sun_path)); + serv.substr(1).copy(unix_addr.sun_path+1,sizeof(unix_addr.sun_path)-1); + } + else // socket in filesystem + serv.copy(unix_addr.sun_path,sizeof(unix_addr.sun_path)); + // create socket + sid = socket(PF_UNIX,SOCK_STREAM,0); + if( sid < 0 ) + return set_errcode(SOCKET); + dprintf(1)("creating unix socket %s\n",serv.c_str()); + if( setDefaults()<0 ) + { + close(sid); + sid = -1; + return errcode_; + } + // bind the socket + int res = bind(sid,(struct sockaddr*)&unix_addr,sizeof(unix_addr)); + dprintf(1)("bind()=%d (%s)\n",res<0?errno:res,res<0?strerror(errno):"OK"); + if( res<0 ) + { + dprintf(1)("close(fd)\n"); + close(sid); + sid = -1; + return set_errcode(BIND); + } + bound = True; + // start listening for connections + res = listen(sid,backlog); + dprintf(1)("listen()=%d (%s)\n",res<0?errno:res,res<0?strerror(errno):"OK"); + if( res<0 ) + { + dprintf(1)("close(fd)\n"); + close(sid); + sid=-1; + return set_errcode(LISTEN); + } + } // endif type UNIX + else // networked socket (type TCP or UDP) + { + host_ = "localhost"; + port_ = serv; + + struct servent *pse; // service info entry + struct protoent *ppe; // protocol entry + + const char *prot = ( type == UDP ? "udp" : "tcp" ); + + memset(&rmt_addr,0,sizeof(rmt_addr)); + rmt_addr.sin_family = AF_INET; + rmt_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + // try to get service by name or port + if( (pse = getservbyname(serv.c_str(),prot)) != 0 ) + rmt_addr.sin_port = pse->s_port; + else if( !(rmt_addr.sin_port = htons((u_short)atoi(serv.c_str()))) ) + return errcode_ = PORT; + // Map protocol name to protocol number + if( !(ppe = getprotobyname(prot)) ) + return errcode_ = PROTOCOL; + // open the socket fd + int soktype = type == TCP ? SOCK_STREAM : SOCK_DGRAM; + sid = socket(PF_INET, soktype, ppe->p_proto); + if( sid < 0 ) + return set_errcode(SOCKET); + dprintf(1)("created server socket, port %d, protocol %d\n", + ntohs((ushort)rmt_addr.sin_port),(int)ppe->p_proto); + // set default options + if( setDefaults()<0 ) + { + close(sid); + sid = -1; + return errcode_; + } + // bind to the socket + int res = bind(sid,(struct sockaddr*)&rmt_addr,sizeof(rmt_addr)); + dprintf(1)("bind()=%d (%s)\n",res<0?errno:res,res<0?strerror(errno):"OK"); + if( res<0 ) + { + dprintf(1)("close(fd)\n"); + close(sid); + sid = -1; + return set_errcode(BIND); + } + bound = True; + // start listening on the socket + if( type == TCP ) + { + res = listen(sid,backlog); + dprintf(1)("listen()=%d (%s)\n",res<0?errno:res,res<0?strerror(errno):"OK"); + if( res<0 ) + { + dprintf(1)("close(fd)\n"); + close(sid); + sid=-1; + return set_errcode(LISTEN); + } + } + else + { + memset(&rmt_addr,0,sizeof(rmt_addr)); + } + } // end else TCP/UDP + + // set non-blocking mode + if( fcntl(sid,F_SETFL,FNDELAY)<0 ) + return set_errcode(SOCKOPT); + + return 0; + //## end Socket::initServer%3C91B9FC0130.body +} + +int Socket::initClient (const string &host, const string &serv, int proto, int wait_ms) +{ + //## begin Socket::initClient%3C91BA16008E.body preserve=yes + errcode_ = errno_sys_ = 0; + sid = -1; + server = False; + connected = False; + type = proto; + host_ = host; + port_ = serv; + if( type == UNIX ) + { + // setup socket address + string path = host +":" +serv; + unix_addr.sun_family = AF_UNIX; + FailWhen(path.length() >= sizeof(unix_addr.sun_path),"socket name too long"); + if( path[0] == '=' ) // abstract socket name + { + memset(unix_addr.sun_path,0,sizeof(unix_addr.sun_path)); + path.substr(1).copy(unix_addr.sun_path+1,sizeof(unix_addr.sun_path)-1); + } + else // socket in filesystem + path.copy(unix_addr.sun_path,sizeof(unix_addr.sun_path)); + // create socket + sid = socket(PF_UNIX,SOCK_STREAM,0); + if( sid < 0 ) + return set_errcode(SOCKET); + dprintf(1)("connecting unix socket to %s\n",path.c_str()); + if( setDefaults()<0 ) + { + close(sid); + sid = -1; + return errcode_; + } + } // endif type UNIX + else // networked socket (type TCP or UDP) + { + // opens a client socket + struct servent *pse; // service info entry + struct hostent *phe; // server host entry + struct protoent *ppe; // protocol entry + string host_addr; // address of server host + + memset(&rmt_addr,0,sizeof(rmt_addr)); + rmt_addr.sin_family = AF_INET; + + const char *prot = ( proto == UDP ? "udp" : "tcp" ); + + // try to get service by name or port + if( (pse = getservbyname(serv.c_str(),prot)) != 0 ) + rmt_addr.sin_port = pse->s_port; + else if( !(rmt_addr.sin_port = htons((u_short)atoi(serv.c_str()))) ) + return errcode_ = PORT; + // try to get host by name + if( (phe = gethostbyname(host.c_str())) != 0 ) + { + if( phe->h_addrtype != AF_INET ) + return errcode_ = BADADDRTYPE; + host_addr = inet_ntoa(*((struct in_addr*)*(phe->h_addr_list))); + } + else + host_addr = host; + // try using dot notation + if( (rmt_addr.sin_addr.s_addr = inet_addr(host_addr.c_str())) == INADDR_NONE ) + return errcode_ = BADHOST; + // Map protocol name to protocol number + if( !(ppe = getprotobyname(prot)) ) + return errcode_ = PROTOCOL; + dprintf(1)("connecting client socket to %s:%s, protocol %d\n", + host_addr.c_str(),port_.c_str(),ppe->p_proto); + // open the socket fd + int soktype = type == TCP ? SOCK_STREAM : SOCK_DGRAM; + sid = socket(PF_INET,soktype,ppe->p_proto); + if( sid < 0 ) + return set_errcode(SOCKET); + // set default options + if( setDefaults()<0 ) + { + close(sid); + sid = -1; + return errcode_; + } + } + + // set non-blocking mode + if( fcntl(sid,F_SETFL,FNDELAY)<0 ) + return set_errcode(SOCKOPT); + // try to connect + if( wait_ms >= 0 ) + return connect(wait_ms); + return 0; + //## end Socket::initClient%3C91BA16008E.body +} + +string Socket::errstr () const +{ + //## begin Socket::errstr%F1A741D4FEED.body preserve=yes + static char const *s_errstr[] = { + "OK", + "Can't create socket (%d: %s)", + "Can't bind local address (%d: %s)", + "Can't connect to server (%d: %s)", + "Can't accept client socket (%d: %s)", + "Bad server host name given", + "Bad address type", + "Read error (%d: %s)", + "Write error (%d: %s)", + "Remote client closed connection (%d: %s)", + "Couldn't read/write whole message (%d: %s)", + "Invalid operation", + "setsockopt() or getsockopt() failure (%d: %s)", + "wrong port/service specified (%d: %s)", + "invalid protocol (%d: %s)", + "listen() error (%d: %s)", + "timeout (%d: %s)", + "connect in progress (%d: %s)", + "No more clients (%d: %s)", + "General failure", + "Uninitialized socket" + }; + if( errcode_ < NOINIT || errcode_ > 0 ) + return ""; + return Debug::ssprintf(s_errstr[-errcode_],errno,strerror(errno)); + //## end Socket::errstr%F1A741D4FEED.body +} + +int Socket::connect (int wait_ms) +{ + //## begin Socket::connect%6AE5AA36FEED.body preserve=yes + if( isServer() ) + return errcode_=INVOP; + for(;;) + { + int res; + if( type == UNIX ) + res = ::connect(sid,(struct sockaddr*)&unix_addr,sizeof(unix_addr)); + else + res = ::connect(sid,(struct sockaddr*)&rmt_addr,sizeof(rmt_addr)); + if( !res ) + break; // connected? break out + else + { + dprintf(2)("connect() failed: errno=%d (%s)\n",errno,strerror(errno)); + if( errno == EINPROGRESS || errno == EALREADY ) + { + { + errcode_ = INPROGRESS; + return 0; + } + } + close(sid); + sid = -1; + return set_errcode(CONNECT); + } + } + dprintf(1)("connect() successful\n"); + connected = True; + errcode_ = 0; + return 1; + //## end Socket::connect%6AE5AA36FEED.body +} + +Socket* Socket::accept () +{ + //## begin Socket::accept%1357FC75FEED.body preserve=yes + if( !isServer() ) + { errcode_=INVOP; return 0; } + if( sid<0 ) + { errcode_=NOINIT; return 0; } + if( type == UDP ) + return this; + int id; + if( type == UNIX ) + { + size_t len = sizeof(unix_addr); + id = ::accept(sid,(struct sockaddr*)&unix_addr,&len); + } + else + { + size_t len = sizeof(rmt_addr); + id = ::accept(sid,(struct sockaddr*)&rmt_addr,&len); + } + if( id < 0 ) + { + dprintf(1)("accept() failed, errno=%d (%s)\n",errno,strerror(errno)); + set_errcode(ACCEPT); + return 0; + } + else + { + dprintf(1)("accept() successful\n"); + errcode_=0; + return type == UNIX + ? new Socket(id,unix_addr) + : new Socket(id,rmt_addr); + } + //## end Socket::accept%1357FC75FEED.body +} + +int Socket::read (void *buf, int maxn) +{ + //## begin Socket::read%5264A6A9FEED.body preserve=yes + if( sid<0 ) + return errcode_=NOINIT; + FailWhen(!buf,"null buffer"); + errcode_ = 0; + if( !maxn ) + return 0; + bool sigpipe = False; + + int nread,nleft=maxn; + if( type != UDP ) + { + while( nleft>0 && !errcode_ && !sigpipe ) + { + errno = 0; + int old_counter = sigpipe_counter; + nread = ::read( sid,buf,nleft ); // try to read something + sigpipe = old_counter != sigpipe_counter; // check for SIGPIPE + dprintf(3)("read(%d)=%d%s, errno=%d (%s)\n",nleft,nread, + sigpipe?" SIGPIPE":"",errno,strerror(errno)); + if( Debug(10) && nread>0 ) + printData(buf,min(nread,200)); + if( nread<0 ) // error? + { + if( errno == EWOULDBLOCK || errno == EAGAIN ) + { // if refuses to block, that's OK, return 0 + errcode_ = TIMEOUT; + return maxn - nleft; + } + else // else a real error + return set_errcode(READERR); + } + else if( nread == 0 ) + return errcode_ = PEERCLOSED; + else + { + buf = nread + (char*)buf; + nleft -= nread; + } + } + } + else // UDP socket + { + errno = 0; +// if ((wres=Wait(rtimeout,SWAIT_READ))==0) +// errcode_=SK_TIMEOUT; +// else + socklen_t alen = sizeof(rmt_addr); + if( (nread=recvfrom(sid,(char*)buf,maxn,0, + (struct sockaddr*)&rmt_addr,&alen))<=0 || + errno ) + return set_errcode(READERR); + else + { + nleft = 0; + connected = True; + } + } + + if( sigpipe ) + return errcode_ = PEERCLOSED; + + return maxn-nleft; + //## end Socket::read%5264A6A9FEED.body +} + +int Socket::write (const void *buf, int n) +{ + //## begin Socket::write%139EF112FEED.body preserve=yes + if( sid<0 ) + return errcode_=NOINIT; + FailWhen(!buf,"null buffer"); + errcode_ = 0; + if( !n ) + return 0; + bool sigpipe = False; + + int nleft=n,nwr; + if( type != UDP ) // TCP or UNIX: write to stream + { + while( nleft>0 && !errcode_ && !sigpipe) + { + errno = 0; + int old_counter = sigpipe_counter; + nwr = ::write(sid,buf,nleft); + sigpipe = old_counter != sigpipe_counter; // check for SIGPIPE + dprintf(3)("write(%d)=%d%s, errno=%d (%s)\n",nleft,nwr, + sigpipe?" SIGPIPE":"",errno,strerror(errno)); + if( Debug(10) && nwr>0 ) + printData(buf,min(nwr,200)); + if( nwr<0 ) + { + if( errno == EWOULDBLOCK || errno == EAGAIN ) + { // if refuses to block, that's OK, return 0 + errcode_ = TIMEOUT; + return n - nleft; + } + else // else a real error + return set_errcode(WRITERR); + } + else if( nwr==0 ) + return errcode_ = PEERCLOSED; + else + { + buf = nwr + (char*)buf; + nleft -= nwr; + } + } + } + else // UDP + { + errno = 0; + if( !connected ) + return errcode_ = WRITERR; + if( (nwr = sendto(sid,(char*)buf,n,0,(struct sockaddr*)&rmt_addr, + sizeof(rmt_addr)))<=0 || errno ) + return set_errcode(WRITERR); + else + nleft=0; + } + + if( sigpipe ) + return errcode_ = PEERCLOSED; + + return n - nleft; + //## end Socket::write%139EF112FEED.body +} + +int Socket::shutdown (bool receive, bool send) +{ + //## begin Socket::shutdown%890ACD77FEED.body preserve=yes + FailWhen(!receive && !send,"neither receive nor send specified"); + if( sid<0 ) + return errcode_ = NOINIT; + errcode_ = 0; + int how = receive ? (send ? 2 : 0) : 1; + int res = shutdown(sid,how); + dprintf(1)("shutdown(%d)=%d",how,res); + if( res<0 ) + return set_errcode(SHUTDOWN); + return 0; + //## end Socket::shutdown%890ACD77FEED.body +} + +int Socket::setDefaults () +{ + //## begin Socket::setDefaults%3EE80597FEED.body preserve=yes + if( sid<0 ) + return errcode_ = NOINIT; + + uint val=1; + struct linger lin = { 1,1 }; + + + if( setsockopt(sid,SOL_SOCKET,SO_REUSEADDR,(char*)&val,sizeof(val))<0 ) + return set_errcode(SOCKOPT); + + // no more defaults for UNIX sockets + if( type == UNIX ) + return 0; + + if( setsockopt(sid,SOL_SOCKET,SO_KEEPALIVE,(char*)&val,sizeof(val) )<0) + return set_errcode(SOCKOPT); + + if( setsockopt(sid,SOL_SOCKET,SO_LINGER,(const char*)&lin,sizeof(lin))<0 ) + return set_errcode(SOCKOPT); + + if( getsockopt(sid,SOL_SOCKET,SO_SNDBUF,(char*)&sbuflen,&val)<0 ) + return set_errcode(SOCKOPT); + + if( getsockopt(sid,SOL_SOCKET,SO_RCVBUF,(char*)&rbuflen,&val)<0 ) + return set_errcode(SOCKOPT); + + return 0; + //## end Socket::setDefaults%3EE80597FEED.body +} + +// Additional Declarations + //## begin Socket%3C90CE58024E.declarations preserve=yes + +void Socket::printData (const void *buf,int n) +{ + char hex[64],chars[32]; + chars[20] = 0; + const unsigned char *ch=(const unsigned char*)buf; + for( int i=0; i<n; i++,ch++ ) + { + int pos = i%20; + if( i && !pos ) + { + printf("%-60s%-20s\n",hex,chars); + hex[0] = chars[0] = 0; + } + sprintf(hex+pos*3,"%02x ",(int)*ch); + chars[pos] = (*ch>=32 && *ch<=127) ? *ch : '.'; + } + if( strlen(hex) ) + { + if( n%20 ) + chars[n%20] = 0; + printf("%-60s%-20s\n",hex,chars); + } +} + + +string Socket::sdebug ( int detail,const string &,const char *name ) const +{ + string out; + if( detail>=0 ) // basic detail + { + out = Debug::ssprintf("%s/%d",name?name:"Socket",sid); + if( server ) + Debug::append(out,"S"); + if( connected ) + Debug::append(out,"c"); + } + if( detail >= 1 || detail == -1 ) // normal detail + { + Debug::appendf(out,"err:%d",errcode_); + if( errcode_ ) + Debug::append(out,errstr()); + } + return out; +} + //## end Socket%3C90CE58024E.declarations +//## begin module%3C90D43B0096.epilog preserve=yes +//## end module%3C90D43B0096.epilog diff --git a/CEP/CPA/OCTOPUSSY/src/Net/Socket.h b/CEP/CPA/OCTOPUSSY/src/Net/Socket.h new file mode 100755 index 0000000000000000000000000000000000000000..f40eec712b8525fe86ffb8dab14a5ccc23a501f4 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Net/Socket.h @@ -0,0 +1,382 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C90D43B0094.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C90D43B0094.cm + +//## begin module%3C90D43B0094.cp preserve=no +//## end module%3C90D43B0094.cp + +//## Module: Socket%3C90D43B0094; Package specification +//## Subsystem: OCTOPUSSY::Net%3C90D442031F +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Net\Socket.h + +#ifndef Socket_h +#define Socket_h 1 + +//## begin module%3C90D43B0094.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C90D43B0094.additionalIncludes + +//## begin module%3C90D43B0094.includes preserve=yes +//#include <sys/file.h> +//#include <sys/types.h> +#include <resolv.h> +#include <errno.h> +#include <sys/un.h> +//#include <netinet/in.h> +//#include <netdb.h> +//#include <fcntl.h> +//#include <unistd.h> +//#include <string.h> +//## end module%3C90D43B0094.includes + +//## begin module%3C90D43B0094.declarations preserve=no +//## end module%3C90D43B0094.declarations + +//## begin module%3C90D43B0094.additionalDeclarations preserve=yes +//## end module%3C90D43B0094.additionalDeclarations + + +//## begin Socket%3C90CE58024E.preface preserve=yes +//## end Socket%3C90CE58024E.preface + +//## Class: Socket%3C90CE58024E +//## Category: OCTOPUSSY::Net%3C90CF69020B +//## Subsystem: OCTOPUSSY::Net%3C90D442031F +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +class Socket +{ + //## begin Socket%3C90CE58024E.initialDeclarations preserve=yes + LocalDebugSubContext; + //## end Socket%3C90CE58024E.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: Socket%3C91BA4300F6 + Socket (const string &sname = ""); + + //## Operation: Socket%9FD2BC39FEED; C++ + // Creates server socket + Socket (const string &sname, const string &serv, // service name/port number + int proto = Socket::TCP, int backlog = 5); + + //## Operation: Socket%C15CE2A5FEED; C++ + // Creates client socket + Socket (const string &sname, const string &host, // remote host + const string &serv, // service name/port number + int proto = Socket::TCP, int wait_ms = -1); + + //## Destructor (generated) + ~Socket(); + + + //## Other Operations (specified) + //## Operation: initServer%3C91B9FC0130 + int initServer (const string &serv, int proto = Socket::TCP, int backlog = 5); + + //## Operation: initClient%3C91BA16008E + int initClient (const string &host, const string &serv, int proto = Socket::TCP, int wait_ms = -1); + + //## Operation: errstr%F1A741D4FEED; C++ + string errstr () const; + + //## Operation: ok%3A99B058FEED; C++ + bool ok (); + + //## Operation: connect%6AE5AA36FEED; C++ + // Attempts to connect to a server socket. + int connect (int wait_ms = 0); + + //## Operation: accept%1357FC75FEED; C++ + // Tries to accept an incoming connection on a server socket. + Socket* accept (); + + //## Operation: read%5264A6A9FEED; C++ + // Reads up to maxn bytes from socket. + int read (void *buf, int maxn); + + //## Operation: write%139EF112FEED; C++ + // Writes n bytes to socket. + int write (const void *buf, int n); + + //## Operation: shutdown%890ACD77FEED; C++ + // Shuts down the socket for receive and/or send + int shutdown (bool receive, bool send); + + //## Get and Set Operations for Class Attributes (generated) + + //## Attribute: name%3C90CE5803BA + const string& getName () const; + void setName (const string& value); + + //## Attribute: errcode%3C90CE5803C1 + int errcode () const; + + //## Attribute: errno_sys%3C91B661029C + int errno_sys () const; + + //## Attribute: sid%3C90CE590017 + int getSid () const; + + //## Attribute: type%3C90CE590038 + int getType () const; + + //## Attribute: server%3C90CE590039 + bool isServer () const; + + //## Attribute: connected%3C90CE59009B + bool isConnected () const; + + //## Attribute: host%3CC00CDC00EA + const string& host () const; + + //## Attribute: port%3CC00CE902E8 + const string& port () const; + + // Data Members for Class Attributes + + //## Attribute: sigpipe_counter%3C90CE5803B3 + //## begin Socket::sigpipe_counter%3C90CE5803B3.attr preserve=no public: int {VT} + volatile int sigpipe_counter; + //## end Socket::sigpipe_counter%3C90CE5803B3.attr + + // Additional Public Declarations + //## begin Socket%3C90CE58024E.public preserve=yes + typedef enum { + UDP, // UDP datagram socket + TCP, // TCP (stream) socket over network + UNIX, // unix socket (local) + LOCAL=UNIX + } SocketTypes; + typedef enum { + SK_OK = 0, // Ok + SOCKET = -1, // Can't create socket + BIND = -2, // Can't bind local address + CONNECT = -3, // Can't connect to server + ACCEPT = -4, // Can't accept client socket + BADHOST = -5, // Bad server host name given + BADADDRTYPE = -6, // Bad address type + READERR = -7, // Read error + WRITERR = -8, // Write error + PEERCLOSED = -9, // Remote client closed connection + INCOMPLETE = -10, // Couldn't read/write whole message + INVOP = -11, // Invalid operation + SOCKOPT = -12, // sockopt() failure + PORT = -13, // wrong port/service specified + PROTOCOL = -14, // invalid protocol + LISTEN = -15, // listen() error + TIMEOUT = -16, // timeout + INPROGRESS = -17, // connect() in progress + NOMORECLI = -18, // No more clients + SHUTDOWN = -19, // shutdown() failure + NOINIT = -20 // uninitialized socket + } ErrorCodes; + + // helper function: prints formatted data from buffer + static void printData (const void *buf,int n); + + Declare_sdebug( ); + Declare_debug( ); + //## end Socket%3C90CE58024E.public + protected: + //## Constructors (specified) + //## Operation: Socket%4760B82BFEED; C++ + // Constructs a generic socket for an incoming connection on a server + // socket. + Socket (int id, struct sockaddr_in &sa); + + //## Operation: Socket%3CC95D6E032A + Socket (int id, struct sockaddr_un &sa); + + + //## Other Operations (specified) + //## Operation: setDefaults%3EE80597FEED; C++ + // Sets default socket options + int setDefaults (); + + // Additional Protected Declarations + //## begin Socket%3C90CE58024E.protected preserve=yes + int set_errcode (int n); + //## end Socket%3C90CE58024E.protected + private: + //## Constructors (generated) + Socket(const Socket &right); + + //## Assignment Operation (generated) + Socket & operator=(const Socket &right); + + // Additional Private Declarations + //## begin Socket%3C90CE58024E.private preserve=yes + //## end Socket%3C90CE58024E.private + + private: //## implementation + // Data Members for Class Attributes + + //## begin Socket::name%3C90CE5803BA.attr preserve=no public: string {V} + string name; + //## end Socket::name%3C90CE5803BA.attr + + //## begin Socket::errcode%3C90CE5803C1.attr preserve=no public: int {V} + int errcode_; + //## end Socket::errcode%3C90CE5803C1.attr + + //## begin Socket::errno_sys%3C91B661029C.attr preserve=no public: int {U} + int errno_sys_; + //## end Socket::errno_sys%3C91B661029C.attr + + //## begin Socket::sid%3C90CE590017.attr preserve=no public: int {V} + int sid; + //## end Socket::sid%3C90CE590017.attr + + //## begin Socket::type%3C90CE590038.attr preserve=no public: int {V} + int type; + //## end Socket::type%3C90CE590038.attr + + //## begin Socket::server%3C90CE590039.attr preserve=no public: bool {V} + bool server; + //## end Socket::server%3C90CE590039.attr + + //## begin Socket::connected%3C90CE59009B.attr preserve=no public: bool {V} + bool connected; + //## end Socket::connected%3C90CE59009B.attr + + //## begin Socket::host%3CC00CDC00EA.attr preserve=no public: string {U} + string host_; + //## end Socket::host%3CC00CDC00EA.attr + + //## begin Socket::port%3CC00CE902E8.attr preserve=no public: string {U} + string port_; + //## end Socket::port%3CC00CE902E8.attr + + //## Attribute: sbuflen%3C90CE59009C + //## begin Socket::sbuflen%3C90CE59009C.attr preserve=no protected: int {V} + int sbuflen; + //## end Socket::sbuflen%3C90CE59009C.attr + + //## Attribute: rbuflen%3C90CE5900A1 + //## begin Socket::rbuflen%3C90CE5900A1.attr preserve=no protected: int {V} + int rbuflen; + //## end Socket::rbuflen%3C90CE5900A1.attr + + // Additional Implementation Declarations + //## begin Socket%3C90CE58024E.implementation preserve=yes + bool bound; + struct sockaddr_in rmt_addr; // connected client address (TCP) + struct sockaddr_un unix_addr; // connected client address (UNIX) + //## end Socket%3C90CE58024E.implementation +}; + +//## begin Socket%3C90CE58024E.postscript preserve=yes +//## end Socket%3C90CE58024E.postscript + +// Class Socket + + +//## Other Operations (inline) +inline bool Socket::ok () +{ + //## begin Socket::ok%3A99B058FEED.body preserve=yes + return sid >= 0 && !errcode_; + //## end Socket::ok%3A99B058FEED.body +} + +//## Get and Set Operations for Class Attributes (inline) + +inline const string& Socket::getName () const +{ + //## begin Socket::getName%3C90CE5803BA.get preserve=no + return name; + //## end Socket::getName%3C90CE5803BA.get +} + +inline void Socket::setName (const string& value) +{ + //## begin Socket::setName%3C90CE5803BA.set preserve=no + name = value; + //## end Socket::setName%3C90CE5803BA.set +} + +inline int Socket::errcode () const +{ + //## begin Socket::errcode%3C90CE5803C1.get preserve=no + return errcode_; + //## end Socket::errcode%3C90CE5803C1.get +} + +inline int Socket::errno_sys () const +{ + //## begin Socket::errno_sys%3C91B661029C.get preserve=no + return errno_sys_; + //## end Socket::errno_sys%3C91B661029C.get +} + +inline int Socket::getSid () const +{ + //## begin Socket::getSid%3C90CE590017.get preserve=no + return sid; + //## end Socket::getSid%3C90CE590017.get +} + +inline int Socket::getType () const +{ + //## begin Socket::getType%3C90CE590038.get preserve=no + return type; + //## end Socket::getType%3C90CE590038.get +} + +inline bool Socket::isServer () const +{ + //## begin Socket::isServer%3C90CE590039.get preserve=no + return server; + //## end Socket::isServer%3C90CE590039.get +} + +inline bool Socket::isConnected () const +{ + //## begin Socket::isConnected%3C90CE59009B.get preserve=no + return connected; + //## end Socket::isConnected%3C90CE59009B.get +} + +inline const string& Socket::host () const +{ + //## begin Socket::host%3CC00CDC00EA.get preserve=no + return host_; + //## end Socket::host%3CC00CDC00EA.get +} + +inline const string& Socket::port () const +{ + //## begin Socket::port%3CC00CE902E8.get preserve=no + return port_; + //## end Socket::port%3CC00CE902E8.get +} + +//## begin module%3C90D43B0094.epilog preserve=yes +inline int Socket::set_errcode ( int n ) +{ + errno_sys_ = errno; + return errcode_ = n; +} +//## end module%3C90D43B0094.epilog + + +#endif + + +// Detached code regions: +#if 0 +//## begin Socket::setSigpipe%3C9205370382.body preserve=yes + sigpipe = True; +//## end Socket::setSigpipe%3C9205370382.body + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist b/CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist new file mode 100644 index 0000000000000000000000000000000000000000..3bac89f6362a6b4713b56352288c4655895045ca --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist @@ -0,0 +1,57 @@ +/LogDebug 380 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/src/WorkProcess.h:36 +/LogError 383 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/src/WorkProcess.h:36 +/LogFatal 384 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/src/WorkProcess.h:36 +/LogNormal 385 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/src/WorkProcess.h:36 +/LogWarning 382 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/src/WorkProcess.h:36 +/MsgLog 381 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/src/WorkProcess.h:36 +Add 319 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:7 +Argv 311 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:8 +Bind 279 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:9 +Bound 278 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:10 +Bye 88 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:11 +Client 287 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:12 +Connected 305 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:13 +Connection 316 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:14 +ConnectionMgrWP 276 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:15 +Dispatcher 107 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:16 +Down 109 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:17 +Duplicate 304 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:18 +Error 280 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:19 +Event 92 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:20 +FailConnect 101 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:21 +Fatal 285 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:22 +GW 282 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:23 +GWClientWP 104 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:24 +GWServerWP 100 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:25 +Gateway 87 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:26 +GatewayWP 89 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:27 +Heartbeat 96 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:28 +Hello 102 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:29 +Host 298 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:30 +Hosts 133 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:31 +Index 360 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/UVD/src/UVD.aidlist:12 +Init 105 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:33 +Input 98 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:34 +List 130 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:35 +Local 91 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:36 +LoggerWP 114 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:37 +#Message 95 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:38 +Network 313 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:39 +Open 314 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:40 +Peers 303 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:41 +Port 297 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:42 +Ports 128 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:43 +Publish 99 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:44 +Reconnect 108 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:45 +Remote 94 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:46 +Reopen 90 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:47 +Server 131 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:48 +Signal 93 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:49 +State 301 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:50 +Subscribe 106 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:51 +Subscriptions 86 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:52 +Timeout 103 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:53 +:Timestamp 85 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:54 +Type 322 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:55 +Up 97 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:56 +WP 286 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:57 diff --git a/CEP/CPA/OCTOPUSSY/src/OctopussyConfig.cc b/CEP/CPA/OCTOPUSSY/src/OctopussyConfig.cc new file mode 100755 index 0000000000000000000000000000000000000000..2dd7fc6640fef8e4cdbe3b1560335985867ab512 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/OctopussyConfig.cc @@ -0,0 +1,170 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3CD0078A01F1.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3CD0078A01F1.cm + +//## begin module%3CD0078A01F1.cp preserve=no +//## end module%3CD0078A01F1.cp + +//## Module: OctopussyConfig%3CD0078A01F1; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\OctopussyConfig.cc + +//## begin module%3CD0078A01F1.additionalIncludes preserve=no +//## end module%3CD0078A01F1.additionalIncludes + +//## begin module%3CD0078A01F1.includes preserve=yes +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +//## end module%3CD0078A01F1.includes + +// OctopussyConfig +#include "OCTOPUSSY/OctopussyConfig.h" +//## begin module%3CD0078A01F1.declarations preserve=no +//## end module%3CD0078A01F1.declarations + +//## begin module%3CD0078A01F1.additionalDeclarations preserve=yes +OctopussyConfig + OctopussyConfig::global_( getenv("HOME") + string("/.octopussy") ); +//## end module%3CD0078A01F1.additionalDeclarations + + +// Class OctopussyConfig + +OctopussyConfig::OctopussyConfig (const string &confdir) + //## begin OctopussyConfig::OctopussyConfig%3CD005FD01DC.hasinit preserve=no + //## end OctopussyConfig::OctopussyConfig%3CD005FD01DC.hasinit + //## begin OctopussyConfig::OctopussyConfig%3CD005FD01DC.initialization preserve=yes + : configdir(confdir) + //## end OctopussyConfig::OctopussyConfig%3CD005FD01DC.initialization +{ + //## begin OctopussyConfig::OctopussyConfig%3CD005FD01DC.body preserve=yes + //## end OctopussyConfig::OctopussyConfig%3CD005FD01DC.body +} + + + +//## Other Operations (implementation) +void OctopussyConfig::init (int argc, const char **argv) +{ + //## begin OctopussyConfig::init%3CD0060C00A7.body preserve=yes + if( configdir[configdir.length()-1] != '/' ) + configdir += '/'; + + // set command line + string localfile; + args_.resize(argc); + for( int i=0; i<argc; i++ ) + { + args_[i] = argv[i]; + if( args_[i].length() > 5 && args_[i].substr(args_[i].length()-5) == ".conf" ) + localfile = args_[i]; + } + + // determine config filenames + // global config file: + string globalfile = "octopussy.conf"; + // set hostname and host-specific config file: + char hname[1024]; + FailWhen(gethostname(hname,sizeof(hname))<0,"gethostname(): "+string(strerror(errno))); + fullHostname_ = hname; + // strip off domain name, if needed + size_t pos = fullHostname_.find_first_of('.'); + if( pos != string::npos ) + hostname_ = fullHostname_.substr(0,pos); + else + hostname_ = fullHostname_; + string hostfile = hostname_+".conf"; + + // appName_ and app-specific config file: + string progfile; + if( argc ) + { + appPath_ = argv[0]; + size_t pos = appPath_.find_last_of('/'); + if( pos != string::npos ) + appName_ = appPath_.substr(pos+1); + else + appName_ = appPath_; + progfile += appName_ + ".conf"; + } + // now, load files from global directory first + merge(configdir + globalfile,True,True); + merge(configdir + hostfile,True,True); + if( progfile.length() ) + merge(configdir + progfile,True,True); + // merge in (and override) with local config files, if any + merge(globalfile,True,True); + merge(hostfile,True,True); + if( progfile.length() ) + merge( progfile,True,True); + // merge in local file, if specified + if( localfile.length() ) + merge( localfile,True,True); + // finally, merge in command line + merge(args_,True); + + dprintf(0)("%d entries configured\n",config().size()); + if( Debug(3) ) + { + for( CCMI iter = config().begin(); iter != config().end(); iter++ ) + dprintf(3)("entry %s=%s\n",iter->first.c_str(),iter->second.c_str()); + } + //## end OctopussyConfig::init%3CD0060C00A7.body +} + +bool OctopussyConfig::getOption (const string &name) const +{ + //## begin OctopussyConfig::getOption%3CD0061B0258.body preserve=yes + string dum; + return getOption(name,dum); + //## end OctopussyConfig::getOption%3CD0061B0258.body +} + +bool OctopussyConfig::getOption (const string &name, int &value) const +{ + //## begin OctopussyConfig::getOption%3CD0063503BD.body preserve=yes + string val; + if( !getOption(name,val) ) + return False; + value = atoi(val.c_str()); + return True; + //## end OctopussyConfig::getOption%3CD0063503BD.body +} + +bool OctopussyConfig::getOption (string name, string &value) const +{ + //## begin OctopussyConfig::getOption%3CD006460137.body preserve=yes + if( name[0] != '-' ) + name = '-' + name; + + for( int i=1; i < argc(); i++ ) + { + if( !argv(i).compare(name,0,name.length()) ) + { + // specified as "-ovalue" + if( argv(i).length() > name.length() ) + value = argv(i).substr(name.length()); + // specified as "-o value" + else if( i < argc()-1 ) + value = argv(i+1); + else + value = ""; + return True; + } + } + return False; + //## end OctopussyConfig::getOption%3CD006460137.body +} + +// Additional Declarations + //## begin OctopussyConfig%3CD00368038B.declarations preserve=yes + //## end OctopussyConfig%3CD00368038B.declarations + +//## begin module%3CD0078A01F1.epilog preserve=yes +//## end module%3CD0078A01F1.epilog diff --git a/CEP/CPA/OCTOPUSSY/src/OctopussyConfig.h b/CEP/CPA/OCTOPUSSY/src/OctopussyConfig.h new file mode 100755 index 0000000000000000000000000000000000000000..03ddc55efe5e23ca05196deb9c1b7bc560c9892c --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/OctopussyConfig.h @@ -0,0 +1,229 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3CD0078A01DD.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3CD0078A01DD.cm + +//## begin module%3CD0078A01DD.cp preserve=no +//## end module%3CD0078A01DD.cp + +//## Module: OctopussyConfig%3CD0078A01DD; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\OctopussyConfig.h + +#ifndef OctopussyConfig_h +#define OctopussyConfig_h 1 + +//## begin module%3CD0078A01DD.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3CD0078A01DD.additionalIncludes + +//## begin module%3CD0078A01DD.includes preserve=yes +#include <vector> +#include <string> +//## end module%3CD0078A01DD.includes + +// ConfigMgr +#include "DMI/ConfigMgr.h" +//## begin module%3CD0078A01DD.declarations preserve=no +//## end module%3CD0078A01DD.declarations + +//## begin module%3CD0078A01DD.additionalDeclarations preserve=yes +//## end module%3CD0078A01DD.additionalDeclarations + + +//## begin OctopussyConfig%3CD00368038B.preface preserve=yes +//## end OctopussyConfig%3CD00368038B.preface + +//## Class: OctopussyConfig%3CD00368038B +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +class OctopussyConfig : public ConfigMgr //## Inherits: <unnamed>%3CD0077A0021 +{ + //## begin OctopussyConfig%3CD00368038B.initialDeclarations preserve=yes + //## end OctopussyConfig%3CD00368038B.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: OctopussyConfig%3CD005FD01DC + OctopussyConfig (const string &confdir); + + + //## Other Operations (specified) + //## Operation: init%3CD0060C00A7 + void init (int argc, const char **argv); + + //## Operation: argc%3CD008910330 + int argc () const; + + //## Operation: argv%3CD00896034B + const string & argv (int i) const; + + //## Operation: getOption%3CD0061B0258 + bool getOption (const string &name) const; + + //## Operation: getOption%3CD0063503BD + bool getOption (const string &name, int &value) const; + + //## Operation: getOption%3CD006460137 + bool getOption (string name, string &value) const; + + //## Operation: initGlobal%3CD0064F01D0 + static void initGlobal (int argc, const char **argv); + + //## Get and Set Operations for Class Attributes (generated) + + //## Attribute: appName%3CD005CA01C5 + const string& appName () const; + + //## Attribute: appPath%3CD005D2037F + const string& appPath () const; + + //## Attribute: hostname%3CD005DB00A7 + const string& hostname () const; + + //## Attribute: fullHostname%3CD005E2027E + const string& fullHostname () const; + + //## Attribute: args%3CD005ED031A + const vector<string>& args () const; + + // Additional Public Declarations + //## begin OctopussyConfig%3CD00368038B.public preserve=yes + static const OctopussyConfig & global(); + + string sdebug (int=0) const; + const char *debug (int=0) const { return sdebug().c_str(); } + //## end OctopussyConfig%3CD00368038B.public + protected: + // Additional Protected Declarations + //## begin OctopussyConfig%3CD00368038B.protected preserve=yes + //## end OctopussyConfig%3CD00368038B.protected + + private: + // Additional Private Declarations + //## begin OctopussyConfig%3CD00368038B.private preserve=yes + //## end OctopussyConfig%3CD00368038B.private + + private: //## implementation + // Data Members for Class Attributes + + //## Attribute: configdir%3CD0059E0009 + //## begin OctopussyConfig::configdir%3CD0059E0009.attr preserve=no private: string {U} + string configdir; + //## end OctopussyConfig::configdir%3CD0059E0009.attr + + //## begin OctopussyConfig::appName%3CD005CA01C5.attr preserve=no public: string {U} + string appName_; + //## end OctopussyConfig::appName%3CD005CA01C5.attr + + //## begin OctopussyConfig::appPath%3CD005D2037F.attr preserve=no public: string {U} + string appPath_; + //## end OctopussyConfig::appPath%3CD005D2037F.attr + + //## begin OctopussyConfig::hostname%3CD005DB00A7.attr preserve=no public: string {U} + string hostname_; + //## end OctopussyConfig::hostname%3CD005DB00A7.attr + + //## begin OctopussyConfig::fullHostname%3CD005E2027E.attr preserve=no public: string {U} + string fullHostname_; + //## end OctopussyConfig::fullHostname%3CD005E2027E.attr + + //## begin OctopussyConfig::args%3CD005ED031A.attr preserve=no public: vector<string> {U} + vector<string> args_; + //## end OctopussyConfig::args%3CD005ED031A.attr + + // Additional Implementation Declarations + //## begin OctopussyConfig%3CD00368038B.implementation preserve=yes + static OctopussyConfig global_; + //## end OctopussyConfig%3CD00368038B.implementation +}; + +//## begin OctopussyConfig%3CD00368038B.postscript preserve=yes +//## end OctopussyConfig%3CD00368038B.postscript + +// Class OctopussyConfig + + +//## Other Operations (inline) +inline int OctopussyConfig::argc () const +{ + //## begin OctopussyConfig::argc%3CD008910330.body preserve=yes + return args_.size(); + //## end OctopussyConfig::argc%3CD008910330.body +} + +inline const string & OctopussyConfig::argv (int i) const +{ + //## begin OctopussyConfig::argv%3CD00896034B.body preserve=yes + return args_[i]; + //## end OctopussyConfig::argv%3CD00896034B.body +} + +inline void OctopussyConfig::initGlobal (int argc, const char **argv) +{ + //## begin OctopussyConfig::initGlobal%3CD0064F01D0.body preserve=yes + global_.init(argc,argv); + //## end OctopussyConfig::initGlobal%3CD0064F01D0.body +} + +//## Get and Set Operations for Class Attributes (inline) + +inline const string& OctopussyConfig::appName () const +{ + //## begin OctopussyConfig::appName%3CD005CA01C5.get preserve=no + return appName_; + //## end OctopussyConfig::appName%3CD005CA01C5.get +} + +inline const string& OctopussyConfig::appPath () const +{ + //## begin OctopussyConfig::appPath%3CD005D2037F.get preserve=no + return appPath_; + //## end OctopussyConfig::appPath%3CD005D2037F.get +} + +inline const string& OctopussyConfig::hostname () const +{ + //## begin OctopussyConfig::hostname%3CD005DB00A7.get preserve=no + return hostname_; + //## end OctopussyConfig::hostname%3CD005DB00A7.get +} + +inline const string& OctopussyConfig::fullHostname () const +{ + //## begin OctopussyConfig::fullHostname%3CD005E2027E.get preserve=no + return fullHostname_; + //## end OctopussyConfig::fullHostname%3CD005E2027E.get +} + +inline const vector<string>& OctopussyConfig::args () const +{ + //## begin OctopussyConfig::args%3CD005ED031A.get preserve=no + return args_; + //## end OctopussyConfig::args%3CD005ED031A.get +} + +//## begin module%3CD0078A01DD.epilog preserve=yes +inline const OctopussyConfig & OctopussyConfig::global() +{ + return global_; +} + +inline string OctopussyConfig::sdebug (int=0) const +{ + return "Config("+hostname_+","+appName_+")"; +} +//## end module%3CD0078A01DD.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/OctopussyDebugContext.cc b/CEP/CPA/OCTOPUSSY/src/OctopussyDebugContext.cc new file mode 100755 index 0000000000000000000000000000000000000000..9a6633e0e10dc563eeb1a5965ce15cdeb13d4124 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/OctopussyDebugContext.cc @@ -0,0 +1,40 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7FA335026A.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7FA335026A.cm + +//## begin module%3C7FA335026A.cp preserve=no +//## end module%3C7FA335026A.cp + +//## Module: OctopussyDebugContext%3C7FA335026A; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\OctopussyDebugContext.cc + +//## begin module%3C7FA335026A.additionalIncludes preserve=no +//## end module%3C7FA335026A.additionalIncludes + +//## begin module%3C7FA335026A.includes preserve=yes +//## end module%3C7FA335026A.includes + +// OctopussyDebugContext +#include "OCTOPUSSY/OctopussyDebugContext.h" +//## begin module%3C7FA335026A.declarations preserve=no +//## end module%3C7FA335026A.declarations + +//## begin module%3C7FA335026A.additionalDeclarations preserve=yes +InitDebugContext(OctopussyDebugContext,"Octopussy"); +//## end module%3C7FA335026A.additionalDeclarations + + +// Class OctopussyDebugContext + +// Additional Declarations + //## begin OctopussyDebugContext%3C7FA3020068.declarations preserve=yes + //## end OctopussyDebugContext%3C7FA3020068.declarations + +//## begin module%3C7FA335026A.epilog preserve=yes +//## end module%3C7FA335026A.epilog diff --git a/CEP/CPA/OCTOPUSSY/src/OctopussyDebugContext.h b/CEP/CPA/OCTOPUSSY/src/OctopussyDebugContext.h new file mode 100755 index 0000000000000000000000000000000000000000..a0487977078e0cbe285f1e6bb6ff38263d7a2535 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/OctopussyDebugContext.h @@ -0,0 +1,83 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7FA335024C.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7FA335024C.cm + +//## begin module%3C7FA335024C.cp preserve=no +//## end module%3C7FA335024C.cp + +//## Module: OctopussyDebugContext%3C7FA335024C; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\OctopussyDebugContext.h + +#ifndef OctopussyDebugContext_h +#define OctopussyDebugContext_h 1 + +//## begin module%3C7FA335024C.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C7FA335024C.additionalIncludes + +//## begin module%3C7FA335024C.includes preserve=yes +//## end module%3C7FA335024C.includes + +//## begin module%3C7FA335024C.declarations preserve=no +//## end module%3C7FA335024C.declarations + +//## begin module%3C7FA335024C.additionalDeclarations preserve=yes +//## end module%3C7FA335024C.additionalDeclarations + + +//## begin OctopussyDebugContext%3C7FA3020068.preface preserve=yes +//## end OctopussyDebugContext%3C7FA3020068.preface + +//## Class: OctopussyDebugContext%3C7FA3020068 +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +class OctopussyDebugContext +{ + //## begin OctopussyDebugContext%3C7FA3020068.initialDeclarations preserve=yes + LocalDebugContext; + //## end OctopussyDebugContext%3C7FA3020068.initialDeclarations + + public: + // Additional Public Declarations + //## begin OctopussyDebugContext%3C7FA3020068.public preserve=yes + //## end OctopussyDebugContext%3C7FA3020068.public + + protected: + // Additional Protected Declarations + //## begin OctopussyDebugContext%3C7FA3020068.protected preserve=yes + //## end OctopussyDebugContext%3C7FA3020068.protected + + private: + // Additional Private Declarations + //## begin OctopussyDebugContext%3C7FA3020068.private preserve=yes + //## end OctopussyDebugContext%3C7FA3020068.private + + private: //## implementation + // Additional Implementation Declarations + //## begin OctopussyDebugContext%3C7FA3020068.implementation preserve=yes + //## end OctopussyDebugContext%3C7FA3020068.implementation + +}; + +//## begin OctopussyDebugContext%3C7FA3020068.postscript preserve=yes +//## end OctopussyDebugContext%3C7FA3020068.postscript + +// Class OctopussyDebugContext + +//## begin module%3C7FA335024C.epilog preserve=yes +//## end module%3C7FA335024C.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/Subscriptions.cc b/CEP/CPA/OCTOPUSSY/src/Subscriptions.cc new file mode 100755 index 0000000000000000000000000000000000000000..ffbf71d22c4fdc4a1e748da48e108ccd91199530 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Subscriptions.cc @@ -0,0 +1,179 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C999E14021C.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C999E14021C.cm + +//## begin module%3C999E14021C.cp preserve=no +//## end module%3C999E14021C.cp + +//## Module: Subscriptions%3C999E14021C; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Subscriptions.cc + +//## begin module%3C999E14021C.additionalIncludes preserve=no +//## end module%3C999E14021C.additionalIncludes + +//## begin module%3C999E14021C.includes preserve=yes +//## end module%3C999E14021C.includes + +// Subscriptions +#include "OCTOPUSSY/Subscriptions.h" +//## begin module%3C999E14021C.declarations preserve=no +//## end module%3C999E14021C.declarations + +//## begin module%3C999E14021C.additionalDeclarations preserve=yes +//## end module%3C999E14021C.additionalDeclarations + + +// Class Subscriptions + +Subscriptions::Subscriptions() + //## begin Subscriptions::Subscriptions%3C999C8400AF_const.hasinit preserve=no + //## end Subscriptions::Subscriptions%3C999C8400AF_const.hasinit + //## begin Subscriptions::Subscriptions%3C999C8400AF_const.initialization preserve=yes + : pksize( sizeof(size_t) ) + //## end Subscriptions::Subscriptions%3C999C8400AF_const.initialization +{ + //## begin Subscriptions::Subscriptions%3C999C8400AF_const.body preserve=yes + //## end Subscriptions::Subscriptions%3C999C8400AF_const.body +} + + + +//## Other Operations (implementation) +bool Subscriptions::add (const HIID& id, const MsgAddress &scope) +{ + //## begin Subscriptions::add%3C999D010361.body preserve=yes + // check if it matches an existing subscription + for( SSI iter = subs.begin(); iter != subs.end(); iter++ ) + { + // new sub is a strict subset of existing one? no change then + if( id.subsetOf(iter->mask) && scope.subsetOf(iter->scope) ) + return False; + // new sub extends existing one? Update + if( iter->mask.subsetOf(id) && iter->scope.subsetOf(scope) ) + { + pksize += id.packSize() - iter->mask.packSize() + + scope.packSize() - iter->scope.packSize(); + iter->mask = id; + iter->scope = scope; + return True; + } + // else keep on looking + } + // not found, so add a subscription + SubElement newelem = { id,scope }; + subs.push_back(newelem); + pksize += id.packSize() + scope.packSize() + 2*sizeof(size_t); + return True; + //## end Subscriptions::add%3C999D010361.body +} + +bool Subscriptions::remove (const HIID &id) +{ + //## begin Subscriptions::remove%3C999D40033A.body preserve=yes + bool ret = False; + for( SSI iter = subs.begin(); iter != subs.end(); ) + { + // remove all subsets of specified ID + if( iter->mask.subsetOf(id) ) + { + pksize -= iter->mask.packSize() + iter->scope.packSize() + 2*sizeof(size_t); + subs.erase(iter++); + ret = True; + } + else + iter++; + } + return ret; + //## end Subscriptions::remove%3C999D40033A.body +} + +void Subscriptions::clear () +{ + //## begin Subscriptions::clear%3C999E0B0223.body preserve=yes + subs.clear(); + pksize = sizeof(size_t); + //## end Subscriptions::clear%3C999E0B0223.body +} + +bool Subscriptions::merge (const Subscriptions &other) +{ + //## begin Subscriptions::merge%3C999D64004D.body preserve=yes + bool ret = False; + for( CSSI iter = other.subs.begin(); iter != other.subs.end(); iter++ ) + ret |= add(iter->mask,iter->scope); + return ret; + //## end Subscriptions::merge%3C999D64004D.body +} + +bool Subscriptions::matches (const Message &msg) const +{ + //## begin Subscriptions::matches%3C999D780005.body preserve=yes + for( CSSI iter = subs.begin(); iter != subs.end(); iter++ ) + if( msg.id().matches(iter->mask) && msg.from().matches(iter->scope) ) + return True; + return False; + //## end Subscriptions::matches%3C999D780005.body +} + +size_t Subscriptions::pack (void* block, size_t &nleft) const +{ + //## begin Subscriptions::pack%3C99AC2F01DF.body preserve=yes + size_t hdrsize = sizeof(size_t)*(1+2*subs.size()); + Assert(hdrsize <= pksize ); // make sure our accounting is right + FailWhen(nleft<hdrsize,"block too small"); + size_t * hdr = static_cast<size_t*>(block); + char * data = static_cast<char*>(block) + hdrsize; + + *(hdr++) = subs.size(); + nleft -= hdrsize; + + for( CSSI iter = subs.begin(); iter != subs.end(); iter++ ) + { + size_t sz1 = iter->mask.pack(data,nleft); data += sz1; + size_t sz2 = iter->scope.pack(data,nleft); data += sz2; + *(hdr++) = sz1; + *(hdr++) = sz2; + hdrsize += sz1+sz2; + } + Assert( hdrsize==pksize ); + return hdrsize; + //## end Subscriptions::pack%3C99AC2F01DF.body +} + +void Subscriptions::unpack (const void* block, size_t sz) +{ + //## begin Subscriptions::unpack%3C99AC2F022F.body preserve=yes + FailWhen(sz<sizeof(size_t),"corrupt block"); + subs.clear(); + pksize = sz; + const size_t * hdr = static_cast<const size_t*>(block); + int n = static_cast<int>(*(hdr++)); + size_t chksize = sizeof(size_t)*(1+2*n); + FailWhen(sz<chksize,"corrupt block"); + const char * data = static_cast<const char*>(block) + chksize; + while( n-->0 ) + { + size_t sz1 = *(hdr++), sz2 = *(hdr++); + chksize += sz1 + sz2; + FailWhen(sz<chksize,"corrupt block"); + SubElement newelem; + newelem.mask.unpack(data,sz1); data += sz1; + newelem.scope.unpack(data,sz2); data += sz2; + subs.push_back(newelem); + } + FailWhen(sz!=chksize,"corrupt block"); + //## end Subscriptions::unpack%3C99AC2F022F.body +} + +// Additional Declarations + //## begin Subscriptions%3C999C8400AF.declarations preserve=yes + //## end Subscriptions%3C999C8400AF.declarations + +//## begin module%3C999E14021C.epilog preserve=yes +//## end module%3C999E14021C.epilog diff --git a/CEP/CPA/OCTOPUSSY/src/Subscriptions.h b/CEP/CPA/OCTOPUSSY/src/Subscriptions.h new file mode 100755 index 0000000000000000000000000000000000000000..89d51dd9156427eb307db28056a5a0aa75733798 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Subscriptions.h @@ -0,0 +1,151 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C999E140208.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C999E140208.cm + +//## begin module%3C999E140208.cp preserve=no +//## end module%3C999E140208.cp + +//## Module: Subscriptions%3C999E140208; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Subscriptions.h + +#ifndef Subscriptions_h +#define Subscriptions_h 1 + +//## begin module%3C999E140208.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C999E140208.additionalIncludes + +//## begin module%3C999E140208.includes preserve=yes +#include <list> +//## end module%3C999E140208.includes + +// HIID +#include "DMI/HIID.h" +// MsgAddress +#include "OCTOPUSSY/MsgAddress.h" +// Message +#include "OCTOPUSSY/Message.h" +//## begin module%3C999E140208.declarations preserve=no +//## end module%3C999E140208.declarations + +//## begin module%3C999E140208.additionalDeclarations preserve=yes +//## end module%3C999E140208.additionalDeclarations + + +//## begin Subscriptions%3C999C8400AF.preface preserve=yes +//## end Subscriptions%3C999C8400AF.preface + +//## Class: Subscriptions%3C999C8400AF +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +//## Uses: <unnamed>%3C99C776028F;MsgAddress { -> } +//## Uses: <unnamed>%3C99C78F0168;HIID { -> } +//## Uses: <unnamed>%3C99C7CF0084;Message { -> } + +class Subscriptions +{ + //## begin Subscriptions%3C999C8400AF.initialDeclarations preserve=yes + //## end Subscriptions%3C999C8400AF.initialDeclarations + + public: + //## Constructors (generated) + Subscriptions(); + + + //## Other Operations (specified) + //## Operation: add%3C999D010361 + bool add (const HIID& id, const MsgAddress &scope); + + //## Operation: remove%3C999D40033A + bool remove (const HIID &id); + + //## Operation: clear%3C999E0B0223 + void clear (); + + //## Operation: size%3C99C0BB0378 + int size () const; + + //## Operation: merge%3C999D64004D + bool merge (const Subscriptions &other); + + //## Operation: matches%3C999D780005 + bool matches (const Message &msg) const; + + //## Operation: pack%3C99AC2F01DF + // Stores HIID into raw data block + size_t pack (void* block, size_t &nleft) const; + + //## Operation: unpack%3C99AC2F022F + void unpack (const void* block, size_t sz); + + //## Operation: packSize%3C99AC2F027F + // Returns # of bytes required to store the HIID + size_t packSize () const; + + // Additional Public Declarations + //## begin Subscriptions%3C999C8400AF.public preserve=yes + //## end Subscriptions%3C999C8400AF.public + + protected: + // Additional Protected Declarations + //## begin Subscriptions%3C999C8400AF.protected preserve=yes + //## end Subscriptions%3C999C8400AF.protected + + private: + // Additional Private Declarations + //## begin Subscriptions%3C999C8400AF.private preserve=yes + //## end Subscriptions%3C999C8400AF.private + + private: //## implementation + // Additional Implementation Declarations + //## begin Subscriptions%3C999C8400AF.implementation preserve=yes + typedef struct { HIID mask; MsgAddress scope; } SubElement; + typedef list<SubElement> SubSet; + SubSet subs; + typedef SubSet::iterator SSI; + typedef SubSet::const_iterator CSSI; + + // this always keep track of the pack-size of the set. + // it is updated by add() and remove(). + size_t pksize; + //## end Subscriptions%3C999C8400AF.implementation +}; + +//## begin Subscriptions%3C999C8400AF.postscript preserve=yes +//## end Subscriptions%3C999C8400AF.postscript + +// Class Subscriptions + + +//## Other Operations (inline) +inline int Subscriptions::size () const +{ + //## begin Subscriptions::size%3C99C0BB0378.body preserve=yes + return subs.size(); + //## end Subscriptions::size%3C99C0BB0378.body +} + +inline size_t Subscriptions::packSize () const +{ + //## begin Subscriptions::packSize%3C99AC2F027F.body preserve=yes + return pksize; + //## end Subscriptions::packSize%3C99AC2F027F.body +} + +//## begin module%3C999E140208.epilog preserve=yes +//## end module%3C999E140208.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/Timestamp.cc b/CEP/CPA/OCTOPUSSY/src/Timestamp.cc new file mode 100755 index 0000000000000000000000000000000000000000..dd9fdd5c49f08af665fde6aa75f04e877d6bd05b --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Timestamp.cc @@ -0,0 +1,128 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7F3B77034D.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7F3B77034D.cm + +//## begin module%3C7F3B77034D.cp preserve=no +//## end module%3C7F3B77034D.cp + +//## Module: Timestamp%3C7F3B77034D; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Timestamp.cc + +//## begin module%3C7F3B77034D.additionalIncludes preserve=no +//## end module%3C7F3B77034D.additionalIncludes + +//## begin module%3C7F3B77034D.includes preserve=yes +#include <math.h> +//## end module%3C7F3B77034D.includes + +// Timestamp +#include "OCTOPUSSY/Timestamp.h" +//## begin module%3C7F3B77034D.declarations preserve=no +//## end module%3C7F3B77034D.declarations + +//## begin module%3C7F3B77034D.additionalDeclarations preserve=yes +//## end module%3C7F3B77034D.additionalDeclarations + + +// Class Timestamp + +//## begin Timestamp::tsnow%3C8F68EA004C.attr preserve=no private: static Timestamp {U} +Timestamp Timestamp::tsnow; +//## end Timestamp::tsnow%3C8F68EA004C.attr + +Timestamp::Timestamp (double sec1) + //## begin Timestamp::Timestamp%3C95C5F90389.hasinit preserve=no + //## end Timestamp::Timestamp%3C95C5F90389.hasinit + //## begin Timestamp::Timestamp%3C95C5F90389.initialization preserve=yes + //## end Timestamp::Timestamp%3C95C5F90389.initialization +{ + //## begin Timestamp::Timestamp%3C95C5F90389.body preserve=yes + sec_ = (long) floor(sec1); + usec_ = (long) floor((sec1-sec_)*1e+6); + //## end Timestamp::Timestamp%3C95C5F90389.body +} + + + +//## Other Operations (implementation) +const Timestamp & Timestamp::now (Timestamp *pts) +{ + //## begin Timestamp::now%3C8F67DD00BD.body preserve=yes + static struct timeval tm; + gettimeofday(&tm,0); + pts->sec_ = tm.tv_sec; + pts->usec_ = tm.tv_usec; + return *pts; + //## end Timestamp::now%3C8F67DD00BD.body +} + +string Timestamp::toString (const char *format) const +{ + //## begin Timestamp::toString%3CA06AE50335.body preserve=yes + time_t tm = sec_; + char tmp[256]; + strftime(tmp,sizeof(tmp),format,localtime(&tm)); + return tmp; + //## end Timestamp::toString%3CA06AE50335.body +} + +Timestamp & Timestamp::operator += (const Timestamp &other) +{ + //## begin Timestamp::operator +=%3C7F3D500287.body preserve=yes + sec_ += other.sec_; + usec_ += other.usec_; + normalize(); + return *this; + //## end Timestamp::operator +=%3C7F3D500287.body +} + +Timestamp & Timestamp::operator -= (const Timestamp &other) +{ + //## begin Timestamp::operator -=%3C7F3D720312.body preserve=yes + sec_ -= other.sec_; + usec_ -= other.usec_; + normalize(); + return *this; + //## end Timestamp::operator -=%3C7F3D720312.body +} + +void Timestamp::normalize () +{ + //## begin Timestamp::normalize%3C7F3E68035C.body preserve=yes + while( usec_ >= 1000000 ) + { + sec_++; + usec_ -= 1000000; + } + while( usec_ < 0 ) + { + sec_--; + usec_ += 1000000; + } + //## end Timestamp::normalize%3C7F3E68035C.body +} + +// Additional Declarations + //## begin Timestamp%3C7F3B1D025E.declarations preserve=yes + //## end Timestamp%3C7F3B1D025E.declarations + +//## begin module%3C7F3B77034D.epilog preserve=yes +//## end module%3C7F3B77034D.epilog + + +// Detached code regions: +#if 0 +//## begin Timestamp::Timestamp%3C7F3B1D025E_const.body preserve=yes + struct timeval tm; + gettimeofday(&tm,0); + sec_ = tm.tv_sec; + usec_ = tm.tv_usec; +//## end Timestamp::Timestamp%3C7F3B1D025E_const.body + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/Timestamp.h b/CEP/CPA/OCTOPUSSY/src/Timestamp.h new file mode 100755 index 0000000000000000000000000000000000000000..3574f6035bd28e396d7852fc27535d9b30951a4d --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/Timestamp.h @@ -0,0 +1,303 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7F3B770339.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7F3B770339.cm + +//## begin module%3C7F3B770339.cp preserve=no +//## end module%3C7F3B770339.cp + +//## Module: Timestamp%3C7F3B770339; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\Timestamp.h + +#ifndef Timestamp_h +#define Timestamp_h 1 + +//## begin module%3C7F3B770339.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C7F3B770339.additionalIncludes + +//## begin module%3C7F3B770339.includes preserve=yes +#include <sys/time.h> +//## end module%3C7F3B770339.includes + +//## begin module%3C7F3B770339.declarations preserve=no +//## end module%3C7F3B770339.declarations + +//## begin module%3C7F3B770339.additionalDeclarations preserve=yes +#pragma types :Timestamp +//## end module%3C7F3B770339.additionalDeclarations + + +//## begin Timestamp%3C7F3B1D025E.preface preserve=yes +//## end Timestamp%3C7F3B1D025E.preface + +//## Class: Timestamp%3C7F3B1D025E +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +class Timestamp +{ + //## begin Timestamp%3C7F3B1D025E.initialDeclarations preserve=yes + //## end Timestamp%3C7F3B1D025E.initialDeclarations + + public: + //## Constructors (generated) + Timestamp(); + + //## Constructors (specified) + //## Operation: Timestamp%3C7F3B580321 + explicit Timestamp (long sec1, long usec1 = 0); + + //## Operation: Timestamp%3C95C5F90389 + Timestamp (double sec1); + + //## Equality Operations (generated) + bool operator==(const Timestamp &right) const; + + bool operator!=(const Timestamp &right) const; + + //## Relational Operations (generated) + bool operator<(const Timestamp &right) const; + + bool operator>(const Timestamp &right) const; + + bool operator<=(const Timestamp &right) const; + + bool operator>=(const Timestamp &right) const; + + + //## Other Operations (specified) + //## Operation: now%3C8F67DD00BD + static const Timestamp & now (Timestamp *pts = &Timestamp::tsnow); + + //## Operation: toString%3CA06AE50335 + string toString (const char *format = "%H:%M:%S %d/%m/%y") const; + + //## Operation: operator bool%3C8F18500073 + operator bool () const; + + //## Operation: operator !%3C8C9EAA005B + bool operator ! () const; + + //## Operation: operator double%3C9F3EF20221 + operator double () const; + + //## Operation: operator +=%3C7F3D500287 + Timestamp & operator += (const Timestamp &other); + + //## Operation: operator -=%3C7F3D720312 + Timestamp & operator -= (const Timestamp &other); + + //## Operation: operator +%3C7F3D7800CC + Timestamp operator + (const Timestamp &other) const; + + //## Operation: operator -%3C7F3D7E032D + Timestamp operator - (const Timestamp &other) const; + + //## Operation: normalize%3C7F3E68035C + void normalize (); + + //## Get and Set Operations for Class Attributes (generated) + + //## Attribute: sec%3C7F3B2600B2 + long sec () const; + + //## Attribute: usec%3C7F3B2E001D + long usec () const; + + // Additional Public Declarations + //## begin Timestamp%3C7F3B1D025E.public preserve=yes + //## end Timestamp%3C7F3B1D025E.public + + protected: + // Additional Protected Declarations + //## begin Timestamp%3C7F3B1D025E.protected preserve=yes + //## end Timestamp%3C7F3B1D025E.protected + + private: + // Additional Private Declarations + //## begin Timestamp%3C7F3B1D025E.private preserve=yes + //## end Timestamp%3C7F3B1D025E.private + + private: //## implementation + // Data Members for Class Attributes + + //## begin Timestamp::sec%3C7F3B2600B2.attr preserve=no public: long {U} + long sec_; + //## end Timestamp::sec%3C7F3B2600B2.attr + + //## begin Timestamp::usec%3C7F3B2E001D.attr preserve=no public: long {U} + long usec_; + //## end Timestamp::usec%3C7F3B2E001D.attr + + //## Attribute: tsnow%3C8F68EA004C + //## begin Timestamp::tsnow%3C8F68EA004C.attr preserve=no private: static Timestamp {U} + static Timestamp tsnow; + //## end Timestamp::tsnow%3C8F68EA004C.attr + + // Additional Implementation Declarations + //## begin Timestamp%3C7F3B1D025E.implementation preserve=yes + //## end Timestamp%3C7F3B1D025E.implementation + +}; + +//## begin Timestamp%3C7F3B1D025E.postscript preserve=yes +//## end Timestamp%3C7F3B1D025E.postscript + +//## begin Timeval%3C95AC350111.preface preserve=yes +//## end Timeval%3C95AC350111.preface + +//## Class: Timeval%3C95AC350111 +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +//## Uses: <unnamed>%3C95AC4D02E2;Timestamp { -> } + +typedef Timestamp Timeval; +//## begin Timeval%3C95AC350111.postscript preserve=yes +//## end Timeval%3C95AC350111.postscript + +// Class Timestamp + +inline Timestamp::Timestamp() + //## begin Timestamp::Timestamp%3C7F3B1D025E_const.hasinit preserve=no + //## end Timestamp::Timestamp%3C7F3B1D025E_const.hasinit + //## begin Timestamp::Timestamp%3C7F3B1D025E_const.initialization preserve=yes + //## end Timestamp::Timestamp%3C7F3B1D025E_const.initialization +{ + //## begin Timestamp::Timestamp%3C7F3B1D025E_const.body preserve=yes + // default constructor: current time + Timestamp::now(this); + //## end Timestamp::Timestamp%3C7F3B1D025E_const.body +} + +inline Timestamp::Timestamp (long sec1, long usec1) + //## begin Timestamp::Timestamp%3C7F3B580321.hasinit preserve=no + //## end Timestamp::Timestamp%3C7F3B580321.hasinit + //## begin Timestamp::Timestamp%3C7F3B580321.initialization preserve=yes + : sec_(sec1),usec_(usec1) + //## end Timestamp::Timestamp%3C7F3B580321.initialization +{ + //## begin Timestamp::Timestamp%3C7F3B580321.body preserve=yes + //## end Timestamp::Timestamp%3C7F3B580321.body +} + + +inline bool Timestamp::operator==(const Timestamp &right) const +{ + //## begin Timestamp::operator==%3C7F3B1D025E_eq.body preserve=yes + return sec_ == right.sec_ && usec_ == right.usec_; + //## end Timestamp::operator==%3C7F3B1D025E_eq.body +} + +inline bool Timestamp::operator!=(const Timestamp &right) const +{ + //## begin Timestamp::operator!=%3C7F3B1D025E_neq.body preserve=yes + return !((*this) == right); + //## end Timestamp::operator!=%3C7F3B1D025E_neq.body +} + + +inline bool Timestamp::operator<(const Timestamp &right) const +{ + //## begin Timestamp::operator<%3C7F3B1D025E_ls.body preserve=yes + return sec_ == right.sec_ ? usec_ < right.usec_ : sec_ < right.sec_; + //## end Timestamp::operator<%3C7F3B1D025E_ls.body +} + +inline bool Timestamp::operator>(const Timestamp &right) const +{ + //## begin Timestamp::operator>%3C7F3B1D025E_gt.body preserve=yes + return sec_ == right.sec_ ? usec_ > right.usec_ : sec_ > right.sec_; + //## end Timestamp::operator>%3C7F3B1D025E_gt.body +} + +inline bool Timestamp::operator<=(const Timestamp &right) const +{ + //## begin Timestamp::operator<=%3C7F3B1D025E_lseq.body preserve=yes + return sec_ == right.sec_ ? usec_ <= right.usec_ : sec_ < right.sec_; + //## end Timestamp::operator<=%3C7F3B1D025E_lseq.body +} + +inline bool Timestamp::operator>=(const Timestamp &right) const +{ + //## begin Timestamp::operator>=%3C7F3B1D025E_gteq.body preserve=yes + return sec_ == right.sec_ ? usec_ >= right.usec_ : sec_ > right.sec_; + //## end Timestamp::operator>=%3C7F3B1D025E_gteq.body +} + + + +//## Other Operations (inline) +inline Timestamp::operator bool () const +{ + //## begin Timestamp::operator bool%3C8F18500073.body preserve=yes + return sec_ || usec_; + //## end Timestamp::operator bool%3C8F18500073.body +} + +inline bool Timestamp::operator ! () const +{ + //## begin Timestamp::operator !%3C8C9EAA005B.body preserve=yes + return ! static_cast<bool>(*this); + //## end Timestamp::operator !%3C8C9EAA005B.body +} + +inline Timestamp::operator double () const +{ + //## begin Timestamp::operator double%3C9F3EF20221.body preserve=yes + return sec_ + 1e-6*usec_; + //## end Timestamp::operator double%3C9F3EF20221.body +} + +inline Timestamp Timestamp::operator + (const Timestamp &other) const +{ + //## begin Timestamp::operator +%3C7F3D7800CC.body preserve=yes + Timestamp res = *this; + return res += other; + //## end Timestamp::operator +%3C7F3D7800CC.body +} + +inline Timestamp Timestamp::operator - (const Timestamp &other) const +{ + //## begin Timestamp::operator -%3C7F3D7E032D.body preserve=yes + Timestamp res = *this; + return res -= other; + //## end Timestamp::operator -%3C7F3D7E032D.body +} + +//## Get and Set Operations for Class Attributes (inline) + +inline long Timestamp::sec () const +{ + //## begin Timestamp::sec%3C7F3B2600B2.get preserve=no + return sec_; + //## end Timestamp::sec%3C7F3B2600B2.get +} + +inline long Timestamp::usec () const +{ + //## begin Timestamp::usec%3C7F3B2E001D.get preserve=no + return usec_; + //## end Timestamp::usec%3C7F3B2E001D.get +} + +//## begin module%3C7F3B770339.epilog preserve=yes +//## end module%3C7F3B770339.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/WPInterface.cc b/CEP/CPA/OCTOPUSSY/src/WPInterface.cc new file mode 100755 index 0000000000000000000000000000000000000000..3f0ea0a154a289a67dc4b7e723f8c705740a4764 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/WPInterface.cc @@ -0,0 +1,740 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C8F26A30123.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C8F26A30123.cm + +//## begin module%3C8F26A30123.cp preserve=no +//## end module%3C8F26A30123.cp + +//## Module: WPInterface%3C8F26A30123; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\WPInterface.cc + +//## begin module%3C8F26A30123.additionalIncludes preserve=no +//## end module%3C8F26A30123.additionalIncludes + +//## begin module%3C8F26A30123.includes preserve=yes +#include "OctopussyConfig.h" +//## end module%3C8F26A30123.includes + +// Dispatcher +#include "OCTOPUSSY/Dispatcher.h" +// WPInterface +#include "OCTOPUSSY/WPInterface.h" +//## begin module%3C8F26A30123.declarations preserve=no +//## end module%3C8F26A30123.declarations + +//## begin module%3C8F26A30123.additionalDeclarations preserve=yes +//## end module%3C8F26A30123.additionalDeclarations + + +// Class WPInterface + +//## begin WPInterface::logLevel%3CA07E5F00D8.attr preserve=no public: static int {U} 2 +int WPInterface::logLevel_ = 2; +//## end WPInterface::logLevel%3CA07E5F00D8.attr + +WPInterface::WPInterface (AtomicID wpc) + //## begin WPInterface::WPInterface%3C7CBB10027A.hasinit preserve=no + //## end WPInterface::WPInterface%3C7CBB10027A.hasinit + //## begin WPInterface::WPInterface%3C7CBB10027A.initialization preserve=yes + : DebugContext(wpc.toString(),&OctopussyDebugContext::getDebugContext()), + config(OctopussyConfig::global()), + address_(wpc),autoCatch_(False),dsp_(0), + queue_(0),wpid_(wpc) + //## end WPInterface::WPInterface%3C7CBB10027A.initialization +{ + //## begin WPInterface::WPInterface%3C7CBB10027A.body preserve=yes + full_lock = receive_lock = started = False; + //## end WPInterface::WPInterface%3C7CBB10027A.body +} + + +WPInterface::~WPInterface() +{ + //## begin WPInterface::~WPInterface%3C7B6A3702E5_dest.body preserve=yes + //## end WPInterface::~WPInterface%3C7B6A3702E5_dest.body +} + + + +//## Other Operations (implementation) +void WPInterface::attach (Dispatcher* pdsp) +{ + //## begin WPInterface::attach%3C7CBAED007B.body preserve=yes + dsp_ = pdsp; + //## end WPInterface::attach%3C7CBAED007B.body +} + +void WPInterface::do_init () +{ + //## begin WPInterface::do_init%3C99B0070017.body preserve=yes + setNeedRepoll(False); + full_lock = receive_lock = started = False; + if( autoCatch() ) + { + try { + init(); + } + catch(std::exception &exc) { + lprintf(0,LogFatal,"caught exception in init(): %s; shutting down",exc.what()); + dsp()->detach(this,True); + } + } + else + init(); + //## end WPInterface::do_init%3C99B0070017.body +} + +bool WPInterface::do_start () +{ + //## begin WPInterface::do_start%3C99B00B00D1.body preserve=yes + log("starting up",2); + MessageRef ref(new Message(MsgHello|address()),DMI::ANON|DMI::WRITE); + publish(ref); + if( autoCatch() ) + { + try { + raiseNeedRepoll( start() ); + } + catch(std::exception &exc) { + lprintf(0,LogFatal,"caught exception in start(): %s; shutting down",exc.what()); + dsp()->detach(this,True); + } + } + else + raiseNeedRepoll( start() ); + // publish subscriptions (even if empty) + started = True; + publishSubscriptions(); + return needRepoll(); + //## end WPInterface::do_start%3C99B00B00D1.body +} + +void WPInterface::do_stop () +{ + //## begin WPInterface::do_stop%3C99B00F0254.body preserve=yes + log("stopping",2); + MessageRef ref(new Message(MsgBye|address()),DMI::ANON|DMI::WRITE); + publish(ref); + if( autoCatch() ) + { + try { + stop(); + } + catch(std::exception &exc) { + lprintf(0,LogError,"caught exception in stop(): %s; ignoring",exc.what()); + } + } + else + stop(); + //## end WPInterface::do_stop%3C99B00F0254.body +} + +void WPInterface::init () +{ + //## begin WPInterface::init%3C7F882B00E6.body preserve=yes + //## end WPInterface::init%3C7F882B00E6.body +} + +bool WPInterface::start () +{ + //## begin WPInterface::start%3C7E4A99016B.body preserve=yes + return False; + //## end WPInterface::start%3C7E4A99016B.body +} + +void WPInterface::stop () +{ + //## begin WPInterface::stop%3C7E4A9C0133.body preserve=yes + //## end WPInterface::stop%3C7E4A9C0133.body +} + +int WPInterface::getPollPriority (ulong tick) +{ + //## begin WPInterface::getPollPriority%3CB55EEA032F.body preserve=yes + // return queue priority, provided a repoll is required + // note that we add the message age (tick - QueueEntry.tick) to its + // priority. Thus, messages that have been sitting undelivered for a while + // (perhaps because the system is saturated with higher-priority messages) + // will eventually get bumped up and become favoured. + if( needRepoll() && !queueLocked() ) + { + const QueueEntry * qe = topOfQueue(); + if( qe ) + { + return max(qe->priority,Message::PRI_LOWEST) + + static_cast<int>(tick - qe->tick); + } + } + return -1; + //## end WPInterface::getPollPriority%3CB55EEA032F.body +} + +bool WPInterface::do_poll (ulong tick) +{ + //## begin WPInterface::do_poll%3C8F13B903E4.body preserve=yes + // Call the virtual poll method, and set needRepoll according to what + // it has returned. + if( autoCatch() ) + { + try { + setNeedRepoll( poll(tick) ); + } + catch(std::exception &exc) { + lprintf(2,LogError,"caught exception in poll(): %s; ignoring",exc.what()); + } + } + else + setNeedRepoll( poll(tick) ); + // return if queue is empty + if( !queue().size() ) + return needRepoll(); + int res = Message::ACCEPT; + // remove message from queue + QueueEntry qe = queue().front(); + queue().pop_front(); + + const Message &msg = qe.mref.deref(); + const HIID &id = msg.id(); + FailWhen( !id.size(),"null message ID" ); + dprintf1(3)("%s: receiving %s\n",sdebug(1).c_str(),msg.debug(1)); + // is it a system event message? + if( id[0] == AidEvent ) + { + if( full_lock ) + return False; + if( id[1] == AidTimeout ) // deliver timeout message + { + FailWhen( id.size() < 2,"malformed "+id.toString()+" message" ); + HIID to_id = id.subId(2); + res = Message::ACCEPT; + if( autoCatch() ) + { + try { + res = timeout(to_id); + } + catch(std::exception &exc) { + lprintf(2,LogError,"caught exception in timeout(): %s; ignoring",exc.what()); + } + } + else + res = timeout(to_id); + if( res == Message::CANCEL ) + dsp()->removeTimeout(this,to_id); + res = Message::ACCEPT; + } + else if( id[1] == AidInput ) // deliver input message + { + FailWhen( id.size() != 3,"malformed "+id.toString()+" message" ); + int fd=id[2],flags=msg.state(); + if( flags ) // no flags? Means the input has been already removed. Ignore + { + res = Message::ACCEPT; + if( autoCatch() ) + { + try { + res = input(fd,flags); + } + catch(std::exception &exc) { + lprintf(2,LogError,"caught exception in input(): %s; ignoring",exc.what()); + } + } + else + res = input(fd,flags); + if( res == Message::CANCEL ) + dsp()->removeInput(this,fd,flags); + res = Message::ACCEPT; + } + } + else if( id[1] == AidSignal ) // deliver input message + { + FailWhen( id.size() != 3,"malformed "+id.toString()+" message" ); + int signum = id[2]; + res = Message::ACCEPT; + if( autoCatch() ) + { + try { + res = signal(signum); + } + catch(std::exception &exc) { + lprintf(2,LogError,"caught exception in signal(): %s; ignoring",exc.what()); + } + } + else + res = signal(signum); + if( res == Message::CANCEL ) + dsp()->removeSignal(this,signum); + res = Message::ACCEPT; + } + else + Throw("unexpected event" + id.toString()); + // Once the event has been delivered, reset its state to 0. + // This helps the dispatcher keep track of when a new event message is + // required (as opposed to updating a previous message that's still + // undelivered). See Dispatcher::checkEvents() for details. + if( qe.mref.isWritable() ) + qe.mref().setState(0); + } + else // deliver regular message + { + if( receive_lock || full_lock ) + return False; + // lock + receive_lock = True; + res = Message::ACCEPT; + if( autoCatch() ) + { + try { + res = receive(qe.mref); + } + catch(std::exception &exc) { + lprintf(2,LogError,"caught exception in receive(): %s; ignoring message",exc.what()); + } + } + else + res = receive(qe.mref); + receive_lock = False; + } + // dispence of queue() accordingly + if( res == Message::ACCEPT ) // message accepted, remove from queue + { + dprintf(3)("result code: OK, de-queuing\n"); + } + else // message not accepted, stays in queue + { + FailWhen( !qe.mref.valid(),"message was not accepted but its ref was detached or xferred" ); + if( res == Message::HOLD ) + { + dprintf(3)("result code: HOLD, leaving at head of queue\n"); + queue().push_front(qe); + return needRepoll(); + } + else if( res == Message::REQUEUE ) + { + dprintf(3)("result code: REQUEUE\n"); + // requeue - re-insert into queue() according to priority + enqueue(qe.mref,tick); // this sets repoll if head of queue has changed + } + } + // ask for repoll if head of queue has changed + if( queue().size() ) + { + // this resets the age at the head of the queue. Effectively, this means + // we have a "queue age" rather than a message age. + queue().front().tick = tick; + if( queue().front().mref != qe.mref ) + return setNeedRepoll(True); + } + + return needRepoll(); + //## end WPInterface::do_poll%3C8F13B903E4.body +} + +bool WPInterface::poll (ulong ) +{ + //## begin WPInterface::poll%3CB55D0E01C2.body preserve=yes + return False; + //## end WPInterface::poll%3CB55D0E01C2.body +} + +bool WPInterface::enqueue (const MessageRef &msg, ulong tick) +{ + //## begin WPInterface::enqueue%3C8F204A01EF.body preserve=yes + int pri = msg->priority(); + // iterate from end of queue() as long as msg priority is higher + MQI iter = queue().begin(); + int count = 0; + while( iter != queue().end() && iter->priority >= pri ) + iter++,count++; + // if inserting at head of queue (which is end), then raise the repoll flag + if( !count ) + { + dprintf(3)("queueing [%s] at head of queue\n",msg->debug(1)); + setNeedRepoll(True); + } + else + dprintf(3)("queueing [%s] at h+%d\n",msg->debug(1),count); + QueueEntry qe = { msg,pri,tick }; + queue().insert(iter,qe); + return needRepoll(); + //## end WPInterface::enqueue%3C8F204A01EF.body +} + +bool WPInterface::dequeue (const HIID &id, MessageRef *ref) +{ + //## begin WPInterface::dequeue%3C8F204D0370.body preserve=yes + bool erased_head = True; + for( MQI iter = queue().begin(); iter != queue().end(); ) + { + if( id.matches( iter->mref->id() ) ) + { + // is this the head of the queue? + erased_head |= ( iter == queue().begin() ); + if( ref ) + *ref = iter->mref; // xfer the reference + queue().erase(iter++); + // we're done if a ref was asked for + if( ref ) + break; + } + else + iter++; + } + return raiseNeedRepoll( erased_head && queue().size() ); + //## end WPInterface::dequeue%3C8F204D0370.body +} + +bool WPInterface::dequeue (int pos, MessageRef *ref) +{ + //## begin WPInterface::dequeue%3C8F205103D0.body preserve=yes + FailWhen( (uint)pos >= queue().size(),"dequeue: illegal position" ); + raiseNeedRepoll( !pos && queue().size()>1 ); + // iterate to the req. position + MQI iter = queue().begin(); + while( pos-- ) + iter++; + if( ref ) + *ref = iter->mref; + queue().erase(iter); + return needRepoll(); + //## end WPInterface::dequeue%3C8F205103D0.body +} + +int WPInterface::searchQueue (const HIID &id, int pos, MessageRef *ref) +{ + //## begin WPInterface::searchQueue%3C8F205601EC.body preserve=yes + FailWhen( (uint)pos >= queue().size(),"dequeue: illegal position" ); + // iterate to the req. position + MQI iter = queue().begin(); + for( int i=0; i<pos; i++ ) + iter++; + // start searching + for( ; iter != queue().end(); iter++,pos++ ) + if( id.matches( iter->mref->id() ) ) + { + if( ref ) + *ref = iter->mref.copy(DMI::PRESERVE_RW); + return pos; + } + // not found + return -1; + //## end WPInterface::searchQueue%3C8F205601EC.body +} + +const WPInterface::QueueEntry * WPInterface::topOfQueue () const +{ + //## begin WPInterface::topOfQueue%3C8F206C0071.body preserve=yes + return queue().size() + ? &queue().front() + : 0; + //## end WPInterface::topOfQueue%3C8F206C0071.body +} + +bool WPInterface::queueLocked () const +{ + //## begin WPInterface::queueLocked%3C8F207902AB.body preserve=yes + if( full_lock ) + return True; + if( receive_lock ) + { + const QueueEntry * qe = topOfQueue(); + if( qe && qe->mref->id()[0] != AidEvent ) + return True; + } + return False; + //## end WPInterface::queueLocked%3C8F207902AB.body +} + +bool WPInterface::subscribe (const HIID &id, const MsgAddress &scope) +{ + //## begin WPInterface::subscribe%3C99AB6E0187.body preserve=yes + // If something has changed in the subs, _and_ WP has been started, + // then re-publish the whole thing. + // (If not yet started, then everything will be eventually published + // by do_start(), above) + dprintf(2)("subscribing to %s scope %s\n",id.toString().c_str(),scope.toString().c_str()); + bool change = subscriptions.add(id,scope); + if( change && started ) + publishSubscriptions(); + return change; + //## end WPInterface::subscribe%3C99AB6E0187.body +} + +bool WPInterface::unsubscribe (const HIID &id) +{ + //## begin WPInterface::unsubscribe%3C7CB9C50365.body preserve=yes + // If something has changed in the subs, _and_ WP has been started, + // then re-publish the whole thing. + // (If not yet started, then everything will be eventually published + // by do_start(), above) + dprintf(2)("unsubscribing from %s\n",id.toString().c_str()); + bool change = subscriptions.remove(id); + if( change && started ) + publishSubscriptions(); + return change; + //## end WPInterface::unsubscribe%3C7CB9C50365.body +} + +int WPInterface::receive (MessageRef &mref) +{ + //## begin WPInterface::receive%3C7CC0950089.body preserve=yes + dprintf(1)("unhandled receive(%s)\n",mref->sdebug(1).c_str()); + return Message::ACCEPT; + //## end WPInterface::receive%3C7CC0950089.body +} + +int WPInterface::timeout (const HIID &id) +{ + //## begin WPInterface::timeout%3C7CC2AB02AD.body preserve=yes + dprintf(1)("unhandled timeout(%s)\n",id.toString().c_str()); + return Message::ACCEPT; + //## end WPInterface::timeout%3C7CC2AB02AD.body +} + +int WPInterface::input (int fd, int flags) +{ + //## begin WPInterface::input%3C7CC2C40386.body preserve=yes + dprintf(1)("unhandled input(%d,%x)\n",fd,flags); + return Message::ACCEPT; + //## end WPInterface::input%3C7CC2C40386.body +} + +int WPInterface::signal (int signum) +{ + //## begin WPInterface::signal%3C7DFD240203.body preserve=yes + dprintf(1)("unhandled signal(%s)\n",sys_siglist[signum]); + return Message::ACCEPT; + //## end WPInterface::signal%3C7DFD240203.body +} + +int WPInterface::send (MessageRef msg, MsgAddress to) +{ + //## begin WPInterface::send%3C7CB9E802CF.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + // if not writable, privatize for writing (but not deeply) + if( !msg.isWritable() ) + msg.privatize(DMI::WRITE); + msg().setHops(0); + msg().setFrom(address()); + msg().setState(state()); + dprintf(2)("send [%s] to %s\n",msg->sdebug(1).c_str(),to.toString().c_str()); + // substitute 'Local' for actual addresses + if( to.host() == AidLocal ) + to.host() = address().host(); + if( to.process() == AidLocal ) + to.process() = address().process(); + return dsp()->send(msg,to); + //## end WPInterface::send%3C7CB9E802CF.body +} + +int WPInterface::send (const HIID &id, MsgAddress to, int priority) +{ + //## begin WPInterface::send%3CBDAD020297.body preserve=yes + MessageRef msg( new Message(id,priority),DMI::ANON|DMI::WRITE ); + send(msg,to); + //## end WPInterface::send%3CBDAD020297.body +} + +int WPInterface::publish (MessageRef msg, int scope) +{ + //## begin WPInterface::publish%3C7CB9EB01CF.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + // if not writable, privatize for writing (but not deeply) + if( !msg.isWritable() ) + msg.privatize(DMI::WRITE); + msg().setFrom(address()); + msg().setState(state()); + msg().setHops(0); + dprintf(2)("publish [%s] scope %d\n",msg->sdebug(1).c_str(),scope); + AtomicID host = (scope < Message::GLOBAL) ? address().host() : AidAny; + AtomicID process = (scope < Message::HOST) ? address().process() : AidAny; + return dsp()->send(msg,MsgAddress(AidPublish,AidPublish,process,host)); + //## end WPInterface::publish%3C7CB9EB01CF.body +} + +int WPInterface::publish (const HIID &id, int scope, int priority) +{ + //## begin WPInterface::publish%3CBDACCC028F.body preserve=yes + MessageRef msg( new Message(id,priority),DMI::ANON|DMI::WRITE ); + return publish(msg,scope); + //## end WPInterface::publish%3CBDACCC028F.body +} + +void WPInterface::setState (int newstate, bool delay_publish) +{ + //## begin WPInterface::setState%3CBED9EF0197.body preserve=yes + if( state_ != newstate ) + { + state_ = newstate; + if( started && !delay_publish ) + publish(MsgWPState); + } + //## end WPInterface::setState%3CBED9EF0197.body +} + +void WPInterface::log (string str, int level, AtomicID type) +{ + //## begin WPInterface::log%3CA0457F01BD.body preserve=yes + if( level > logLevel() ) + return; + // see if type override was specified in the string + const char * stypes[] = { "warning:", "error:", "fatal:", "debug:", "normal:" }; + const AtomicID types[] = { LogWarning,LogError,LogFatal,LogDebug,LogNormal }; + for( int i=0; i<4; i++ ) + { + uint len = strlen(stypes[i]); + if( str.length() >= len && !strncasecmp(str.c_str(),stypes[i],len) ) + { + type = types[i]; + // chop the override string off + while( len < str.length() && isspace(str[len]) ) + len++; + str = str.substr(len); + break; + } + } + // duplicate to stdout if appropriate debug level is set + if( level <= DebugLevel ) + { + const char *tps = ""; + if( type == LogWarning ) + tps = stypes[0]; + else if( type == LogError ) + tps = stypes[1]; + Debug::dbg_stream<<sdebug(1)<<":"<<tps<<" "<<str; + if( str[str.length()-1] != '\n' ) + Debug::dbg_stream<<endl; + } + // publish as MsgLog + SmartBlock *bl = new SmartBlock(str.length()); + str.copy(static_cast<char*>(bl->data()),str.length()); + MessageRef mref( + new Message(MsgLog|type|level,bl,DMI::ANON), + DMI::ANON|DMI::WRITE); + publish(mref); + //## end WPInterface::log%3CA0457F01BD.body +} + +void WPInterface::lprintf (int level, int type, const char *format, ... ) +{ + //## begin WPInterface::lprintf%3CA0738D007F.body preserve=yes + if( level > logLevel() ) + return; + // create the string + char str[1024]; + va_list(ap); + va_start(ap,format); + vsnprintf(str,sizeof(str),format,ap); + va_end(ap); + log(str,level,type); + //## end WPInterface::lprintf%3CA0738D007F.body +} + +void WPInterface::lprintf (int level, const char *format, ... ) +{ + //## begin WPInterface::lprintf%3CA0739F0247.body preserve=yes + if( level > logLevel() ) + return; + char str[1024]; + va_list(ap); + va_start(ap,format); + vsnprintf(str,sizeof(str),format,ap); + va_end(ap); + log(str,level,LogNormal); + //## end WPInterface::lprintf%3CA0739F0247.body +} + +// Additional Declarations + //## begin WPInterface%3C7B6A3702E5.declarations preserve=yes + +void WPInterface::publishSubscriptions () +{ + // pack subscriptions into a block + size_t sz = subscriptions.packSize(); + BlockRef bref(new SmartBlock(sz),DMI::ANON|DMI::WRITE); + subscriptions.pack(bref().data(),sz); + // publish it + MessageRef ref( new Message(MsgSubscribe|address(), + bref,0), + DMI::ANONWR); + publish(ref); +} + + +string WPInterface::sdebug ( int detail,const string &,const char *nm ) const +{ + string out; + if( detail>=0 ) // basic detail + { + if( nm ) + out = string(nm) + "/"; + out += address().toString(); + out += Debug::ssprintf("/%08x",this); + Debug::appendf(out,"Q:%d",queue().size()); + } + if( detail >= 1 || detail == -1 ) // normal detail + { + Debug::appendf(out,"st:%d",state_); + } + return out; +} + //## end WPInterface%3C7B6A3702E5.declarations +//## begin module%3C8F26A30123.epilog preserve=yes +//## end module%3C8F26A30123.epilog + + +// Detached code regions: +#if 0 +//## begin WPInterface::subscribe%3C7CB9B70120.body preserve=yes + subscribe(id,MsgAddress( + AidAny,AidAny, + scope < Message::PROCESS ? address().process() : AidAny, + scope < Message::GLOBAL ? address().host() : AidAny)); +//## end WPInterface::subscribe%3C7CB9B70120.body + +//## begin WPInterface::publish%3C99BFA502B0.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + // if not writable, privatize for writing (but not deeply) + if( !msg.isWritable() ) + msg.privatize(DMI::WRITE); + msg().setFrom(address()); + msg().setState(state()); + dprintf(2)("publish [%s] scope %d\n",msg->sdebug(1).c_str(),scope); + AtomicID host = (scope < Message::GLOBAL) ? dsp()->hostId() : AidAny; + AtomicID process = (scope < Message::HOST) ? dsp()->processId() : AidAny; + return dsp()->send(msg,MsgAddress(AidPublish,AidPublish,process,host)); +//## end WPInterface::publish%3C99BFA502B0.body + +//## begin WPInterface::subscribesTo%3C8F14310315.body preserve=yes + // determine minimum subscription scope + int minscope = Message::PROCESS; + if( msg.from().process() != address().process() ) + minscope = Message::HOST; + if( msg.from().host() != address().host() ) + minscope = Message::GLOBAL; + // look thru map + for( CSSI iter = subs.begin(); iter != subs.end(); iter++ ) + if( iter->first.matches(msg.id()) && iter->second >= minscope ) + return True; + return False; +//## end WPInterface::subscribesTo%3C8F14310315.body + +//## begin WPInterface::initSubsIterator%3C98D8090048.body preserve=yes + return subs.begin(); +//## end WPInterface::initSubsIterator%3C98D8090048.body + +//## begin WPInterface::iterateSubs%3C98D81C0077.body preserve=yes + if( iter == +//## end WPInterface::iterateSubs%3C98D81C0077.body + +//## begin WPInterface::wpclass%3C905E8B000E.body preserve=yes + // default wp class is 0 + return 0; +//## end WPInterface::wpclass%3C905E8B000E.body + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/WPInterface.h b/CEP/CPA/OCTOPUSSY/src/WPInterface.h new file mode 100755 index 0000000000000000000000000000000000000000..a110c85ee81ba30dc74c929fb7132e559f8af41c --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/WPInterface.h @@ -0,0 +1,537 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C8F268F00DE.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C8F268F00DE.cm + +//## begin module%3C8F268F00DE.cp preserve=no +//## end module%3C8F268F00DE.cp + +//## Module: WPInterface%3C8F268F00DE; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\WPInterface.h + +#ifndef WPInterface_h +#define WPInterface_h 1 + +//## begin module%3C8F268F00DE.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C8F268F00DE.additionalIncludes + +//## begin module%3C8F268F00DE.includes preserve=yes +#include <list> +#include <set> +#include <queue> +#include "OctopussyConfig.h" +//## end module%3C8F268F00DE.includes + +// CountedRefTarget +#include "DMI/CountedRefTarget.h" +// Subscriptions +#include "OCTOPUSSY/Subscriptions.h" +// OctopussyDebugContext +#include "OCTOPUSSY/OctopussyDebugContext.h" +// Message +#include "OCTOPUSSY/Message.h" + +class Dispatcher; + +//## begin module%3C8F268F00DE.declarations preserve=no +//## end module%3C8F268F00DE.declarations + +//## begin module%3C8F268F00DE.additionalDeclarations preserve=yes +// standard event messages +#pragma aid WP Event Timeout Input Signal Subscribe +// hello/bye/state messages for WPs +#pragma aid Hello Bye State + +// some service messages +const HIID + MsgHello(AidWP|AidHello), + MsgBye(AidWP|AidBye), + MsgWPState(AidWP|AidState), + MsgSubscribe(AidWP|AidSubscribe); + +//## end module%3C8F268F00DE.additionalDeclarations + + +//## begin WPInterface%3C7B6A3702E5.preface preserve=yes +//## end WPInterface%3C7B6A3702E5.preface + +//## Class: WPInterface%3C7B6A3702E5; Abstract +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +//## Uses: <unnamed>%3C7E133B016D;Message { -> } + +class WPInterface : public OctopussyDebugContext, //## Inherits: <unnamed>%3C7FA31F00CE + public SingularRefTarget //## Inherits: <unnamed>%3C8CDD980366 +{ + //## begin WPInterface%3C7B6A3702E5.initialDeclarations preserve=yes + public: + // each WP has its own local debug context (subcontext of Octopussy) + + Debug::Context DebugContext; + ::Debug::Context & getDebugContext() { return DebugContext; }; + const ::Debug::Context & getDebugContext() const { return DebugContext; }; + + typedef struct { MessageRef mref; + int priority; + ulong tick; + } QueueEntry; + + typedef list<QueueEntry> MessageQueue; + //## end WPInterface%3C7B6A3702E5.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: WPInterface%3C7CBB10027A + WPInterface (AtomicID wpc); + + //## Destructor (generated) + virtual ~WPInterface(); + + + //## Other Operations (specified) + //## Operation: wpname%3C83541601B4 + string wpname () const; + + //## Operation: wpid%3C9062180079 + const WPID & wpid () const; + + //## Operation: setAddress%3C98C3600396 + void setAddress (const MsgAddress &addr); + + //## Operation: attach%3C7CBAED007B + void attach (Dispatcher* pdsp); + + //## Operation: isAttached%3C7CBBD101E1 + bool isAttached () const; + + //## Operation: do_init%3C99B0070017 + void do_init (); + + //## Operation: do_start%3C99B00B00D1 + bool do_start (); + + //## Operation: do_stop%3C99B00F0254 + void do_stop (); + + //## Operation: init%3C7F882B00E6 + virtual void init (); + + //## Operation: start%3C7E4A99016B + virtual bool start (); + + //## Operation: stop%3C7E4A9C0133 + virtual void stop (); + + //## Operation: getPollPriority%3CB55EEA032F + // Rreturns a polling priority for this WP. Normally, this is just the + // priority of the top message in the queue (plus the queue age), or <0 + // for no poll required. However, subclasses may choose to redefine + // this if they employ a some custom polling scheme. + // This method is called once per WP per polling loop. + virtual int getPollPriority (ulong tick); + + //## Operation: do_poll%3C8F13B903E4 + bool do_poll (ulong tick); + + //## Operation: poll%3CB55D0E01C2 + virtual bool poll (ulong ); + + //## Operation: enqueue%3C8F204A01EF + // Places ref into the receive queue. Note that the ref is transferred. + // Returns True if WP needs to be repolled. + bool enqueue (const MessageRef &msg, ulong tick); + + //## Operation: dequeue%3C8F204D0370 + // Removes from queue messages matching the id. Returns True if WP + // needs to be repolled. + // If ref is non-0, then removes the first matching message, and + // attaches ref to it. If ref is 0, removes all matching messages. + bool dequeue (const HIID &id, MessageRef *ref = 0); + + //## Operation: dequeue%3C8F205103D0 + // Dequeues the message at the given position. If ref is non-0, then + // attaches ref to the message. Returns True if WP needs to be repolled. + bool dequeue (int pos, MessageRef *ref = 0); + + //## Operation: searchQueue%3C8F205601EC + // Finds first message in queue, starting at pos (0=top), with + // matching id. Returns position of message, or -1 if not found. If ref + // is specified, then attaches it to the message. + int searchQueue (const HIID &id, int pos = 0, MessageRef *ref = 0); + + //## Operation: topOfQueue%3C8F206C0071 + const WPInterface::QueueEntry * topOfQueue () const; + + //## Operation: queueLocked%3C8F207902AB + bool queueLocked () const; + + //## Operation: willForward%3C9079A00325 + // Returns True if this WP will forward this non-local message. + virtual bool willForward (const Message &) const; + + //## Operation: subscribe%3C7CB9B70120 + bool subscribe (const HIID &id, int scope = Message::GLOBAL); + + //## Operation: subscribe%3C99AB6E0187 + bool subscribe (const HIID &id, const MsgAddress &scope); + + //## Operation: unsubscribe%3C7CB9C50365 + bool unsubscribe (const HIID &id); + + //## Operation: receive%3C7CC0950089 + virtual int receive (MessageRef &mref); + + //## Operation: timeout%3C7CC2AB02AD + virtual int timeout (const HIID &id); + + //## Operation: input%3C7CC2C40386 + virtual int input (int fd, int flags); + + //## Operation: signal%3C7DFD240203 + virtual int signal (int signum); + + //## Operation: send%3C7CB9E802CF + // Sends message to specified address. Note that the ref is taken over + // by this call, then privatized for writing. See Dispatcher::send() + // for more details. + int send (MessageRef msg, MsgAddress to); + + //## Operation: send%3CBDAD020297 + int send (const HIID &id, MsgAddress to, int priority = Message::PRI_NORMAL); + + //## Operation: publish%3C7CB9EB01CF + // Publishes message with the specified scope. Note that the ref is + // taken over by this call, then privatized for writing. This method is + // just a shorthand for send(), with "Publish" in some parts of the + // address, as determined by scope). + int publish (MessageRef msg, int scope = Message::GLOBAL); + + //## Operation: publish%3CBDACCC028F + int publish (const HIID &id, int scope = Message::GLOBAL, int priority = Message::PRI_NORMAL); + + //## Operation: setState%3CBED9EF0197 + void setState (int newstate, bool delay_publish = False); + + //## Operation: log%3CA0457F01BD + void log (string str, int level = 0, AtomicID type = LogNormal); + + //## Operation: lprintf%3CA0738D007F + void lprintf (int level, int type, const char *format, ... ); + + //## Operation: lprintf%3CA0739F0247 + void lprintf (int level, const char *format, ... ); + + //## Get and Set Operations for Class Attributes (generated) + + //## Attribute: address%3C7CBA880058 + const MsgAddress& address () const; + + //## Attribute: needRepoll%3C8F18B40315 + bool needRepoll () const; + bool setNeedRepoll (bool value); + + //## Attribute: state%3C8F256E024B + int state () const; + + //## Attribute: logLevel%3CA07E5F00D8 + static int logLevel (); + static void setLogLevel (int value); + + //## Get and Set Operations for Associations (generated) + + //## Association: OCTOPUSSY::<unnamed>%3C7E14150352 + //## Role: WPInterface::dsp%3C7E1416017C + Dispatcher * dsp () const; + + //## Association: OCTOPUSSY::<unnamed>%3C999CBF01D6 + //## Role: WPInterface::subscriptions%3C999CC00015 + const Subscriptions& getSubscriptions () const; + + // Additional Public Declarations + //## begin WPInterface%3C7B6A3702E5.public preserve=yes + bool isLocal (const MsgAddress &addr) + { return addr.peerid() == address().peerid(); }; + bool isLocal (const Message &msg) + { return isLocal(msg.from()); } + bool isLocal (const MessageRef &mref) + { return isLocal(mref->from()); } + + + Declare_sdebug(virtual); + Declare_debug( ); + //## end WPInterface%3C7B6A3702E5.public + protected: + //## Get and Set Operations for Class Attributes (generated) + + //## Attribute: autoCatch%3CBED3720012 + // If set, then all exceptions inside the WP's callbacks will be caught + // and ignored. + bool autoCatch () const; + void setAutoCatch (bool value); + + //## Get and Set Operations for Associations (generated) + + //## Association: OCTOPUSSY::<unnamed>%3CA1A1AB0346 + //## Role: WPInterface::queue%3CA1A1AC01AD + const WPInterface::MessageQueue& queue () const; + + // Additional Protected Declarations + //## begin WPInterface%3C7B6A3702E5.protected preserve=yes + Subscriptions& getSubscriptions (); + + WPInterface::MessageQueue & queue (); + + + // publishes a message containing all current subscriptions + void publishSubscriptions (); + + bool full_lock,receive_lock; + + + const OctopussyConfig & config; + + //## end WPInterface%3C7B6A3702E5.protected + private: + //## Constructors (generated) + WPInterface(); + + WPInterface(const WPInterface &right); + + //## Assignment Operation (generated) + WPInterface & operator=(const WPInterface &right); + + // Additional Private Declarations + //## begin WPInterface%3C7B6A3702E5.private preserve=yes + //## end WPInterface%3C7B6A3702E5.private + + private: //## implementation + // Data Members for Class Attributes + + //## begin WPInterface::address%3C7CBA880058.attr preserve=no public: MsgAddress {U} + MsgAddress address_; + //## end WPInterface::address%3C7CBA880058.attr + + //## begin WPInterface::needRepoll%3C8F18B40315.attr preserve=no public: bool {U} + bool needRepoll_; + //## end WPInterface::needRepoll%3C8F18B40315.attr + + //## begin WPInterface::state%3C8F256E024B.attr preserve=no public: int {U} + int state_; + //## end WPInterface::state%3C8F256E024B.attr + + //## begin WPInterface::autoCatch%3CBED3720012.attr preserve=no protected: bool {U} + bool autoCatch_; + //## end WPInterface::autoCatch%3CBED3720012.attr + + //## begin WPInterface::logLevel%3CA07E5F00D8.attr preserve=no public: static int {U} 2 + static int logLevel_; + //## end WPInterface::logLevel%3CA07E5F00D8.attr + + // Data Members for Associations + + //## Association: OCTOPUSSY::<unnamed>%3C7E14150352 + //## begin WPInterface::dsp%3C7E1416017C.role preserve=no public: Dispatcher {0..* -> 1RFHN} + Dispatcher *dsp_; + //## end WPInterface::dsp%3C7E1416017C.role + + //## Association: OCTOPUSSY::<unnamed>%3C999CBF01D6 + //## begin WPInterface::subscriptions%3C999CC00015.role preserve=no public: Subscriptions { -> 1VHgN} + Subscriptions subscriptions; + //## end WPInterface::subscriptions%3C999CC00015.role + + //## Association: OCTOPUSSY::<unnamed>%3CA1A1AB0346 + //## begin WPInterface::queue%3CA1A1AC01AD.role preserve=no protected: MessageRef { -> 0..*VHgN} + WPInterface::MessageQueue queue_; + //## end WPInterface::queue%3CA1A1AC01AD.role + + // Additional Implementation Declarations + //## begin WPInterface%3C7B6A3702E5.implementation preserve=yes + bool raiseNeedRepoll (bool value) + { return needRepoll_ |= value; } + + bool started; + + WPID wpid_; + + typedef MessageQueue::iterator MQI; + typedef MessageQueue::const_iterator CMQI; + typedef MessageQueue::reverse_iterator MQRI; + typedef MessageQueue::const_reverse_iterator CMQRI; + + //## end WPInterface%3C7B6A3702E5.implementation +}; + +//## begin WPInterface%3C7B6A3702E5.postscript preserve=yes +typedef CountedRef<WPInterface> WPRef; +//## end WPInterface%3C7B6A3702E5.postscript + +// Class WPInterface + + +//## Other Operations (inline) +inline string WPInterface::wpname () const +{ + //## begin WPInterface::wpname%3C83541601B4.body preserve=yes + return address_.wpclass().toString(); + //## end WPInterface::wpname%3C83541601B4.body +} + +inline const WPID & WPInterface::wpid () const +{ + //## begin WPInterface::wpid%3C9062180079.body preserve=yes + return wpid_; + //## end WPInterface::wpid%3C9062180079.body +} + +inline void WPInterface::setAddress (const MsgAddress &addr) +{ + //## begin WPInterface::setAddress%3C98C3600396.body preserve=yes + address_ = addr; + wpid_ = WPID(addr.wpclass(),addr.inst()); + //## end WPInterface::setAddress%3C98C3600396.body +} + +inline bool WPInterface::isAttached () const +{ + //## begin WPInterface::isAttached%3C7CBBD101E1.body preserve=yes + return dsp() != 0; + //## end WPInterface::isAttached%3C7CBBD101E1.body +} + +inline bool WPInterface::willForward (const Message &) const +{ + //## begin WPInterface::willForward%3C9079A00325.body preserve=yes + return False; + //## end WPInterface::willForward%3C9079A00325.body +} + +inline bool WPInterface::subscribe (const HIID &id, int scope) +{ + //## begin WPInterface::subscribe%3C7CB9B70120.body preserve=yes + return subscribe( + id,MsgAddress( + AidAny,AidAny, + scope <= Message::PROCESS ? address().process() : AidAny, + scope <= Message::HOST ? address().host() : AidAny + ) + ); + //## end WPInterface::subscribe%3C7CB9B70120.body +} + +//## Get and Set Operations for Class Attributes (inline) + +inline const MsgAddress& WPInterface::address () const +{ + //## begin WPInterface::address%3C7CBA880058.get preserve=no + return address_; + //## end WPInterface::address%3C7CBA880058.get +} + +inline bool WPInterface::needRepoll () const +{ + //## begin WPInterface::needRepoll%3C8F18B40315.get preserve=no + return needRepoll_; + //## end WPInterface::needRepoll%3C8F18B40315.get +} + +inline bool WPInterface::setNeedRepoll (bool value) +{ + //## begin WPInterface::setNeedRepoll%3C8F18B40315.set preserve=no + needRepoll_ = value; + return value; + //## end WPInterface::setNeedRepoll%3C8F18B40315.set +} + +inline int WPInterface::state () const +{ + //## begin WPInterface::state%3C8F256E024B.get preserve=no + return state_; + //## end WPInterface::state%3C8F256E024B.get +} + +inline bool WPInterface::autoCatch () const +{ + //## begin WPInterface::autoCatch%3CBED3720012.get preserve=no + return autoCatch_; + //## end WPInterface::autoCatch%3CBED3720012.get +} + +inline void WPInterface::setAutoCatch (bool value) +{ + //## begin WPInterface::setAutoCatch%3CBED3720012.set preserve=no + autoCatch_ = value; + //## end WPInterface::setAutoCatch%3CBED3720012.set +} + +inline int WPInterface::logLevel () +{ + //## begin WPInterface::logLevel%3CA07E5F00D8.get preserve=no + return logLevel_; + //## end WPInterface::logLevel%3CA07E5F00D8.get +} + +inline void WPInterface::setLogLevel (int value) +{ + //## begin WPInterface::setLogLevel%3CA07E5F00D8.set preserve=no + logLevel_ = value; + //## end WPInterface::setLogLevel%3CA07E5F00D8.set +} + +//## Get and Set Operations for Associations (inline) + +inline Dispatcher * WPInterface::dsp () const +{ + //## begin WPInterface::dsp%3C7E1416017C.get preserve=no + return dsp_; + //## end WPInterface::dsp%3C7E1416017C.get +} + +inline const Subscriptions& WPInterface::getSubscriptions () const +{ + //## begin WPInterface::getSubscriptions%3C999CC00015.get preserve=no + return subscriptions; + //## end WPInterface::getSubscriptions%3C999CC00015.get +} + +inline const WPInterface::MessageQueue& WPInterface::queue () const +{ + //## begin WPInterface::queue%3CA1A1AC01AD.get preserve=no + return queue_; + //## end WPInterface::queue%3CA1A1AC01AD.get +} + +//## begin module%3C8F268F00DE.epilog preserve=yes +inline Subscriptions& WPInterface::getSubscriptions () +{ return subscriptions; }; + +inline WPInterface::MessageQueue & WPInterface::queue () +{ return queue_; } +//## end module%3C8F268F00DE.epilog + + +#endif + + +// Detached code regions: +#if 0 +//## begin WPInterface::isGateway%3C9083BD0328.body preserve=yes + return False; +//## end WPInterface::isGateway%3C9083BD0328.body + +//## begin WPInterface::wpclass%3C905E8B000E.body preserve=yes + return 0; +//## end WPInterface::wpclass%3C905E8B000E.body + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/WorkProcess.cc b/CEP/CPA/OCTOPUSSY/src/WorkProcess.cc new file mode 100755 index 0000000000000000000000000000000000000000..2c0ecda49c5d2fdcc92a3698759ad1ee01e459c7 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/WorkProcess.cc @@ -0,0 +1,203 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7B7F3000C5.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7B7F3000C5.cm + +//## begin module%3C7B7F3000C5.cp preserve=no +//## end module%3C7B7F3000C5.cp + +//## Module: WorkProcess%3C7B7F3000C5; Package body +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\WorkProcess.cc + +//## begin module%3C7B7F3000C5.additionalIncludes preserve=no +//## end module%3C7B7F3000C5.additionalIncludes + +//## begin module%3C7B7F3000C5.includes preserve=yes +#include "OCTOPUSSY/Dispatcher.h" +#include "OCTOPUSSY/AID-OCTOPUSSY.h" +//## end module%3C7B7F3000C5.includes + +// WorkProcess +#include "OCTOPUSSY/WorkProcess.h" +//## begin module%3C7B7F3000C5.declarations preserve=no +//## end module%3C7B7F3000C5.declarations + +//## begin module%3C7B7F3000C5.additionalDeclarations preserve=yes +//## end module%3C7B7F3000C5.additionalDeclarations + + +// Class WorkProcess + +WorkProcess::WorkProcess (AtomicID wpc) + //## begin WorkProcess::WorkProcess%3C8F25DB014E.hasinit preserve=no + //## end WorkProcess::WorkProcess%3C8F25DB014E.hasinit + //## begin WorkProcess::WorkProcess%3C8F25DB014E.initialization preserve=yes + : WPInterface(wpc) + //## end WorkProcess::WorkProcess%3C8F25DB014E.initialization +{ + //## begin WorkProcess::WorkProcess%3C8F25DB014E.body preserve=yes + //## end WorkProcess::WorkProcess%3C8F25DB014E.body +} + + + +//## Other Operations (implementation) +void WorkProcess::addTimeout (const Timestamp &period, const HIID &id, int flags, int priority) +{ + //## begin WorkProcess::addTimeout%3C7D285803B0.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + return dsp()->addTimeout(this,period,id,flags,priority); + //## end WorkProcess::addTimeout%3C7D285803B0.body +} + +void WorkProcess::addInput (int fd, int flags, int priority) +{ + //## begin WorkProcess::addInput%3C7D2874023E.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + return dsp()->addInput(this,fd,flags,priority); + //## end WorkProcess::addInput%3C7D2874023E.body +} + +void WorkProcess::addSignal (int signum, int flags, volatile int* counter, int priority) +{ + //## begin WorkProcess::addSignal%3C7DFE520239.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + return dsp()->addSignal(this,signum,flags,counter,priority); + //## end WorkProcess::addSignal%3C7DFE520239.body +} + +bool WorkProcess::removeTimeout (const HIID &id) +{ + //## begin WorkProcess::removeTimeout%3C7D287F02C6.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + return dsp()->removeTimeout(this,id); + //## end WorkProcess::removeTimeout%3C7D287F02C6.body +} + +bool WorkProcess::removeInput (int fd, int flags) +{ + //## begin WorkProcess::removeInput%3C7D28A30141.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + return dsp()->removeInput(this,fd,flags); + //## end WorkProcess::removeInput%3C7D28A30141.body +} + +bool WorkProcess::removeSignal (int signum) +{ + //## begin WorkProcess::removeSignal%3C7DFE480253.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + return dsp()->removeSignal(this,signum); + //## end WorkProcess::removeSignal%3C7DFE480253.body +} + +void WorkProcess::detachMyself () +{ + //## begin WorkProcess::detachMyself%3C95A89D015E.body preserve=yes + dsp()->detach(this,True); + //## end WorkProcess::detachMyself%3C95A89D015E.body +} + +const MsgAddress & WorkProcess::attachWP (WPRef &wpref) +{ + //## begin WorkProcess::attachWP%3C95BA1602D9.body preserve=yes + return dsp()->attach(wpref); + //## end WorkProcess::attachWP%3C95BA1602D9.body +} + +const MsgAddress & WorkProcess::attachWP (WPInterface* wp, int flags) +{ + //## begin WorkProcess::attachWP%3C95BA1A02D5.body preserve=yes + return dsp()->attach(wp,flags); + //## end WorkProcess::attachWP%3C95BA1A02D5.body +} + +// Additional Declarations + //## begin WorkProcess%3C8F25430087.declarations preserve=yes + //## end WorkProcess%3C8F25430087.declarations + +//## begin module%3C7B7F3000C5.epilog preserve=yes +//## end module%3C7B7F3000C5.epilog + + +// Detached code regions: +#if 0 +//## begin WorkProcess::lprintf%3CA0738D007F.body preserve=yes + if( level > logLevel() ) + return; + // create the string + char str[1024]; + va_list(ap); + va_start(ap,format); + vsnprintf(str,sizeof(str),format,ap); + va_end(ap); + log(str,level,type); +//## end WorkProcess::lprintf%3CA0738D007F.body + +//## begin WorkProcess::lprintf%3CA0739F0247.body preserve=yes + if( level > logLevel() ) + return; + char str[1024]; + va_list(ap); + va_start(ap,format); + vsnprintf(str,sizeof(str),format,ap); + va_end(ap); + log(str,level,LogNormal); +//## end WorkProcess::lprintf%3CA0739F0247.body + +//## begin WorkProcess::start%3C9216B701CA.body preserve=yes + WPInterface::start(); +//## end WorkProcess::start%3C9216B701CA.body + +//## begin WorkProcess::stop%3C9216C10015.body preserve=yes + WPInterface::stop(); +//## end WorkProcess::stop%3C9216C10015.body + +//## begin WorkProcess::send%3C7CB9E802CF.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + // if not writable, privatize for writing (but not deeply) + if( !msg.isWritable() ) + msg.privatize(DMI::WRITE); + msg().setFrom(address()); + msg().setState(state()); + dprintf(2)("send [%s] to %s\n",msg->sdebug(1).c_str(),to.toString().c_str()); + // substitute 'Local' for actual addresses + if( to.host() == AidLocal ) + to.host() = address().host(); + if( to.process() == AidLocal ) + to.process() = address().process(); + return dsp()->send(msg,to); +//## end WorkProcess::send%3C7CB9E802CF.body + +//## begin WorkProcess::publish%3C7CB9EB01CF.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + // if not writable, privatize for writing (but not deeply) + if( !msg.isWritable() ) + msg.privatize(DMI::WRITE); + msg().setFrom(address()); + msg().setState(state()); + dprintf(2)("publish [%s] scope %d\n",msg->sdebug(1).c_str(),scope); + AtomicID host = (scope < Message::GLOBAL) ? dsp()->hostId() : AidAny; + AtomicID process = (scope < Message::HOST) ? dsp()->processId() : AidAny; + return dsp()->send(msg,MsgAddress(AidPublish,AidPublish,process,host)); +//## end WorkProcess::publish%3C7CB9EB01CF.body + +//## begin WorkProcess::subscribe%3C7CB9B70120.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + dprintf(2)("subscribing to %s\n",id.toString().c_str()); + subscriptions().add(id); + return True; +//## end WorkProcess::subscribe%3C7CB9B70120.body + +//## begin WorkProcess::unsubscribe%3C7CB9C50365.body preserve=yes + FailWhen( !isAttached(),"unattached wp"); + dprintf(2)("unsubscribing from %s\n",id.toString().c_str()); + subscriptions().remove(id); + return True; +//## end WorkProcess::unsubscribe%3C7CB9C50365.body + +#endif diff --git a/CEP/CPA/OCTOPUSSY/src/WorkProcess.h b/CEP/CPA/OCTOPUSSY/src/WorkProcess.h new file mode 100755 index 0000000000000000000000000000000000000000..e48fcf54fd92f07884441de50ccd61245818a173 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/src/WorkProcess.h @@ -0,0 +1,130 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7B7F3000C3.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7B7F3000C3.cm + +//## begin module%3C7B7F3000C3.cp preserve=no +//## end module%3C7B7F3000C3.cp + +//## Module: WorkProcess%3C7B7F3000C3; Package specification +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\WorkProcess.h + +#ifndef WorkProcess_h +#define WorkProcess_h 1 + +//## begin module%3C7B7F3000C3.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C7B7F3000C3.additionalIncludes + +//## begin module%3C7B7F3000C3.includes preserve=yes +//## end module%3C7B7F3000C3.includes + +// WPInterface +#include "OCTOPUSSY/WPInterface.h" +// Dispatcher +#include "OCTOPUSSY/Dispatcher.h" +//## begin module%3C7B7F3000C3.declarations preserve=no +//## end module%3C7B7F3000C3.declarations + +//## begin module%3C7B7F3000C3.additionalDeclarations preserve=yes +#pragma aid /MsgLog /LogNormal /LogWarning /LogError /LogFatal /LogDebug +//## end module%3C7B7F3000C3.additionalDeclarations + + +//## begin WorkProcess%3C8F25430087.preface preserve=yes +//## end WorkProcess%3C8F25430087.preface + +//## Class: WorkProcess%3C8F25430087; Abstract +//## Category: OCTOPUSSY%3BCEC935032A +//## Subsystem: OCTOPUSSY%3C5A73670223 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +//## Uses: <unnamed>%3C8F3679014E;Dispatcher { -> } + +class WorkProcess : public WPInterface //## Inherits: <unnamed>%3C8F263A00E6 +{ + //## begin WorkProcess%3C8F25430087.initialDeclarations preserve=yes + //## end WorkProcess%3C8F25430087.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: WorkProcess%3C8F25DB014E + WorkProcess (AtomicID wpc); + + + //## Other Operations (specified) + //## Operation: addTimeout%3C7D285803B0 + void addTimeout (const Timestamp &period, const HIID &id = HIID(), int flags = 0, int priority = Message::PRI_EVENT); + + //## Operation: addInput%3C7D2874023E + void addInput (int fd, int flags, int priority = Message::PRI_EVENT); + + //## Operation: addSignal%3C7DFE520239 + void addSignal (int signum, int flags = 0, volatile int* counter = 0, int priority = Message::PRI_EVENT); + + //## Operation: removeTimeout%3C7D287F02C6 + bool removeTimeout (const HIID &id); + + //## Operation: removeInput%3C7D28A30141 + bool removeInput (int fd, int flags = EV_FDALL); + + //## Operation: removeSignal%3C7DFE480253 + bool removeSignal (int signum); + + //## Operation: detachMyself%3C95A89D015E + void detachMyself (); + + //## Operation: attachWP%3C95BA1602D9 + const MsgAddress & attachWP (WPRef &wpref); + + //## Operation: attachWP%3C95BA1A02D5 + const MsgAddress & attachWP (WPInterface* wp, int flags); + + // Additional Public Declarations + //## begin WorkProcess%3C8F25430087.public preserve=yes + //## end WorkProcess%3C8F25430087.public + + protected: + // Additional Protected Declarations + //## begin WorkProcess%3C8F25430087.protected preserve=yes + //## end WorkProcess%3C8F25430087.protected + + private: + //## Constructors (generated) + WorkProcess(); + + WorkProcess(const WorkProcess &right); + + //## Assignment Operation (generated) + WorkProcess & operator=(const WorkProcess &right); + + // Additional Private Declarations + //## begin WorkProcess%3C8F25430087.private preserve=yes + //## end WorkProcess%3C8F25430087.private + + private: //## implementation + // Additional Implementation Declarations + //## begin WorkProcess%3C8F25430087.implementation preserve=yes + //## end WorkProcess%3C8F25430087.implementation + +}; + +//## begin WorkProcess%3C8F25430087.postscript preserve=yes +//## end WorkProcess%3C8F25430087.postscript + +// Class WorkProcess + +//## begin module%3C7B7F3000C3.epilog preserve=yes +//## end module%3C7B7F3000C3.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/test/EchoWP.cc b/CEP/CPA/OCTOPUSSY/test/EchoWP.cc new file mode 100755 index 0000000000000000000000000000000000000000..9ce59c47fa6af0d43b4a61b9cd408be499146a7c --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/test/EchoWP.cc @@ -0,0 +1,218 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7E49E90399.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7E49E90399.cm + +//## begin module%3C7E49E90399.cp preserve=no +//## end module%3C7E49E90399.cp + +//## Module: EchoWP%3C7E49E90399; Package body +//## Subsystem: OCTOPUSSY::test%3C7E494F0184 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\test\EchoWP.cc + +//## begin module%3C7E49E90399.additionalIncludes preserve=no +//## end module%3C7E49E90399.additionalIncludes + +//## begin module%3C7E49E90399.includes preserve=yes +#include <sys/time.h> +#include "DMI/DataRecord.h" +//## end module%3C7E49E90399.includes + +// EchoWP +#include "EchoWP.h" +//## begin module%3C7E49E90399.declarations preserve=no +//## end module%3C7E49E90399.declarations + +//## begin module%3C7E49E90399.additionalDeclarations preserve=yes +const HIID MsgPing("Ping"),MsgPong("Pong"),MsgHelloEchoWP(MsgHello|"EchoWP.*"); +//## end module%3C7E49E90399.additionalDeclarations + + +// Class EchoWP + +EchoWP::EchoWP (int pingcount) + //## begin EchoWP::EchoWP%3C7E49B60327.hasinit preserve=no + //## end EchoWP::EchoWP%3C7E49B60327.hasinit + //## begin EchoWP::EchoWP%3C7E49B60327.initialization preserve=yes + : WorkProcess(AidEchoWP),pcount(pingcount) + //## end EchoWP::EchoWP%3C7E49B60327.initialization +{ + //## begin EchoWP::EchoWP%3C7E49B60327.body preserve=yes + blocksize = 64; + pipeline = 1; + invert = 1; + fill = 0x07070707; + msgcount = bytecount = 0; + timecount = 0; + ts = Timestamp::now(); + //## end EchoWP::EchoWP%3C7E49B60327.body +} + + +EchoWP::~EchoWP() +{ + //## begin EchoWP::~EchoWP%3C7E498E00D1_dest.body preserve=yes + //## end EchoWP::~EchoWP%3C7E498E00D1_dest.body +} + + + +//## Other Operations (implementation) +void EchoWP::init () +{ + //## begin EchoWP::init%3C7F884A007D.body preserve=yes + WorkProcess::init(); + + config.get("bs",blocksize); + lprintf(0,"blocksize = %d KB\n",blocksize); + blocksize *= 1024/sizeof(int); + + config.get("pc",pcount); + lprintf(0,"pingcount = %d\n",pcount); + + config.get("pipe",pipeline); + lprintf(0,"pipeline = %d\n",pipeline); + + config.get("fill",fill); + lprintf(0,"fill = %d\n",fill); + + config.get("invert",invert); + lprintf(0,"invert = %d\n",(int)invert); + + if( !pcount ) + subscribe("Ping"); + else if( pcount<0 ) + { + subscribe("Ping"); + subscribe(MsgHelloEchoWP); + } + //## end EchoWP::init%3C7F884A007D.body +} + +bool EchoWP::start () +{ + //## begin EchoWP::start%3C7E4AC70261.body preserve=yes + WorkProcess::start(); + if( pcount>0 ) + sendPing(); + return False; + //## end EchoWP::start%3C7E4AC70261.body +} + +int EchoWP::receive (MessageRef& mref) +{ + //## begin EchoWP::receive%3C7E49AC014C.body preserve=yes + lprintf(4,"received %s\n",mref.debug(10)); + if( mref->id() == MsgPing && mref->from() != address() ) + { + // privatize message & payload + Message & msg = mref.privatize(DMI::WRITE,1); + lprintf(3,"ping(%d) from %s\n",msg["Count"].as_int(),mref->from().toString().c_str()); + // timestamp the reply + int sz = msg["Data"].size(); + msg["Reply.Timestamp"] = Timestamp(); + // invert the data block if it's there + if( msg["Invert"].as_bool() ) + { + int *data = &(msg.setBranch("Data",DMI::WRITE|DMI::PRIVATIZE)); + lprintf(4,"inverting %d ints at %x\n",sz,(int)data); + for( int i=0; i<sz; i++,data++ ) + *data = ~*data; + } + msg.setId(MsgPong); + lprintf(3,"replying with pong(%d)\n",msg["Count"].as_int()); +// stepCounters(sz*sizeof(int)); + send(mref,msg.from()); + } + else if( mref->id() == MsgPong ) + { + lprintf(3,"pong(%d) from %s\n",mref.deref()["Count"].as_int(),mref->from().toString().c_str()); + if( !pcount ) + dsp()->stopPolling(); + else + { + const Message &msg = mref.deref(); + stepCounters(msg["Data"].size()*sizeof(int),msg["Timestamp"]); + sendPing(); + } + } + else if( mref->id().matches(MsgHelloEchoWP) ) + { + if( mref->from() != address() ) // not our own? + { + lprintf(0,"found a friend: %s\n",mref->from().toString().c_str()); + bytecount = 0; + msgcount = 0; + ts = Timestamp::now(); + for( int i=0; i<pipeline; i++ ) + sendPing(); +// addTimeout(1.0); + } + } + return Message::ACCEPT; + //## end EchoWP::receive%3C7E49AC014C.body +} + +int EchoWP::timeout (const HIID &) +{ + //## begin EchoWP::timeout%3C98CB600343.body preserve=yes + sendPing(); + return Message::ACCEPT; + //## end EchoWP::timeout%3C98CB600343.body +} + +// Additional Declarations + //## begin EchoWP%3C7E498E00D1.declarations preserve=yes +void EchoWP::stepCounters ( size_t sz,const Timestamp &stamp ) +{ + msgcount++; + bytecount += sz; + double ts1 = Timestamp::now(); + timecount += ts1 - (double)stamp; + if( ts1 - ts > 10 ) + { + lprintf(0,"%.2f seconds elapsed since last report\n",ts1-ts); + lprintf(0,"%ld round-trip bytes (%.2f MB/s)\n", + bytecount,bytecount*2/(1024*1024*(ts1-ts))); + lprintf(0,"%ld round-trips (%.1f /s)\n", + msgcount,msgcount/(ts1-ts)); + lprintf(0,"%.3f ms average round-trip time\n",timecount/msgcount*1000); + bytecount = msgcount = 0; + ts = ts1; + timecount = 0; + } +} + + +void EchoWP::sendPing () +{ + if( pcount ) + { + Message &msg = *new Message(MsgPing,new DataRecord,DMI::ANON|DMI::WRITE); + msg["Timestamp"] = Timestamp(); + msg["Invert"] = invert; + msg["Data"] <<= new DataField(Tpint,blocksize); + msg["Count"] = pcount; + if( fill ) + { + int sz = msg["Data"].size(); + int *data = &msg["Data"]; + lprintf(4,"filling %d ints at %x\n",sz,(int)data); + for( int i=0; i<sz; i++ ) + data[i] = 0x07070707; + } + lprintf(4,"ping %d, publishing %s\n",pcount,msg.debug(1)); + lprintf(3,"sending ping(%d)\n",msg["Count"].as_int()); + MessageRef ref(msg,DMI::ANON|DMI::WRITE); + publish(ref); + pcount--; +// stepCounters(sz*sizeof(int)); + } +} + //## end EchoWP%3C7E498E00D1.declarations +//## begin module%3C7E49E90399.epilog preserve=yes +//## end module%3C7E49E90399.epilog diff --git a/CEP/CPA/OCTOPUSSY/test/EchoWP.h b/CEP/CPA/OCTOPUSSY/test/EchoWP.h new file mode 100755 index 0000000000000000000000000000000000000000..5c749726c0198f408efcb7c77632a5e2e16bcaf6 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/test/EchoWP.h @@ -0,0 +1,123 @@ +//## begin module%1.4%.codegen_version preserve=yes +// Read the documentation to learn more about C++ code generator +// versioning. +//## end module%1.4%.codegen_version + +//## begin module%3C7E49E90390.cm preserve=no +// %X% %Q% %Z% %W% +//## end module%3C7E49E90390.cm + +//## begin module%3C7E49E90390.cp preserve=no +//## end module%3C7E49E90390.cp + +//## Module: EchoWP%3C7E49E90390; Package specification +//## Subsystem: OCTOPUSSY::test%3C7E494F0184 +//## Source file: F:\lofar8\oms\LOFAR\src-links\OCTOPUSSY\test\EchoWP.h + +#ifndef EchoWP_h +#define EchoWP_h 1 + +//## begin module%3C7E49E90390.additionalIncludes preserve=no +#include "DMI/Common.h" +#include "DMI/DMI.h" +//## end module%3C7E49E90390.additionalIncludes + +//## begin module%3C7E49E90390.includes preserve=yes +//## end module%3C7E49E90390.includes + +// WorkProcess +#include "OCTOPUSSY/WorkProcess.h" +//## begin module%3C7E49E90390.declarations preserve=no +//## end module%3C7E49E90390.declarations + +//## begin module%3C7E49E90390.additionalDeclarations preserve=yes +#pragma aidgroup Testing +#pragma aid EchoWP Ping Pong +#pragma aid Reply Timestamp Invert Data Count +#include "AID-Testing.h" +//## end module%3C7E49E90390.additionalDeclarations + + +//## begin EchoWP%3C7E498E00D1.preface preserve=yes +//## end EchoWP%3C7E498E00D1.preface + +//## Class: EchoWP%3C7E498E00D1 +//## Category: OCTOPUSSY::Testing%3C7E49840235 +//## Subsystem: OCTOPUSSY::test%3C7E494F0184 +//## Persistence: Transient +//## Cardinality/Multiplicity: n + + + +class EchoWP : public WorkProcess //## Inherits: <unnamed>%3C8F26580162 +{ + //## begin EchoWP%3C7E498E00D1.initialDeclarations preserve=yes + //## end EchoWP%3C7E498E00D1.initialDeclarations + + public: + //## Constructors (specified) + //## Operation: EchoWP%3C7E49B60327 + EchoWP (int pingcount = 0); + + //## Destructor (generated) + ~EchoWP(); + + + //## Other Operations (specified) + //## Operation: init%3C7F884A007D + virtual void init (); + + //## Operation: start%3C7E4AC70261 + virtual bool start (); + + //## Operation: receive%3C7E49AC014C + virtual int receive (MessageRef& mref); + + //## Operation: timeout%3C98CB600343 + virtual int timeout (const HIID &); + + // Additional Public Declarations + //## begin EchoWP%3C7E498E00D1.public preserve=yes + //## end EchoWP%3C7E498E00D1.public + + protected: + // Additional Protected Declarations + //## begin EchoWP%3C7E498E00D1.protected preserve=yes + int pcount,blocksize,pipeline,fill; + int invert; + + long bytecount,msgcount; + double ts,timecount; + + void stepCounters ( size_t nb,const Timestamp &stamp ); + + void sendPing (); + //## end EchoWP%3C7E498E00D1.protected + private: + //## Constructors (generated) + EchoWP(const EchoWP &right); + + //## Assignment Operation (generated) + EchoWP & operator=(const EchoWP &right); + + // Additional Private Declarations + //## begin EchoWP%3C7E498E00D1.private preserve=yes + //## end EchoWP%3C7E498E00D1.private + + private: //## implementation + // Additional Implementation Declarations + //## begin EchoWP%3C7E498E00D1.implementation preserve=yes + //## end EchoWP%3C7E498E00D1.implementation + +}; + +//## begin EchoWP%3C7E498E00D1.postscript preserve=yes +//## end EchoWP%3C7E498E00D1.postscript + +// Class EchoWP + +//## begin module%3C7E49E90390.epilog preserve=yes +//## end module%3C7E49E90390.epilog + + +#endif diff --git a/CEP/CPA/OCTOPUSSY/test/Makefile.am b/CEP/CPA/OCTOPUSSY/test/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..b8d49b75f57ca9c45a5b2d229c5e4d3a1cc6c759 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/test/Makefile.am @@ -0,0 +1,48 @@ +CXXFLAGS += -Wno-unknown-pragmas -pg + +INCLUDES = -I$(top_srcdir)/src + +dmi_dir = $(lofar_sharedir)/../DMI + +check_PROGRAMS = test_octopussy + +bin_PROGRAMS = test_gw test_gw0 test_ping test_glish + +test_octopussy_SOURCES = test_octopussy.cc EchoWP.cc AID-Testing-Registry.cc + +test_octopussy_LDADD = $(top_builddir)/src/liboctopussy.la + +test_gw_SOURCES = test_gw.cc EchoWP.cc AID-Testing-Registry.cc + +test_gw_LDADD = $(top_builddir)/src/liboctopussy.la + +test_gw0_SOURCES = test_gw0.cc AID-Testing-Registry.cc + +test_gw0_LDADD = $(top_builddir)/src/liboctopussy.la + +test_ping_SOURCES = test_ping.cc EchoWP.cc AID-Testing-Registry.cc + +test_ping_LDADD = $(top_builddir)/src/liboctopussy.la + +test_glish_SOURCES = test_glish.cc EchoWP.cc AID-Testing-Registry.cc + +test_glish_LDADD = $(top_builddir)/src/Glish/liboctopussy-glish.la \ + $(top_builddir)/src/liboctopussy.la -lglish -lsos -lnpd + +TESTS = test_octopussy + +EXTRA_DIST = + +# script used to generate AID maps +MAPBUILDER = $(dmi_dir)/src/build_aid_maps.pl + +# All .aidlist files below this dir will be scanned +BASELISTDIR = $(lofar_sharedir)/.. + +# Your package's subdirectory +AID_DIR = $(top_srcdir)/test + +aids: + $(MAPBUILDER) `find $(BASELISTDIR) -name \*.aidlist` $(AID_DIR)/*.h + +include $(lofar_sharedir)/Makefile.common diff --git a/CEP/CPA/OCTOPUSSY/test/Testing.aidlist b/CEP/CPA/OCTOPUSSY/test/Testing.aidlist new file mode 100644 index 0000000000000000000000000000000000000000..73a5be854d6c14b0dac27360c3720a2d3b6da958 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/test/Testing.aidlist @@ -0,0 +1,8 @@ +Count 389 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/test/EchoWP.h:36 +Data 81 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/UVD/src/UVD.aidlist:6 +EchoWP 386 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/test/EchoWP.h:35 +Invert 388 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/test/EchoWP.h:36 +Ping 391 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/test/EchoWP.h:35 +Pong 387 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/test/EchoWP.h:35 +Reply 390 ; from /home/oms/LOFAR/CEP/CPA/OCTOPUSSY/test/EchoWP.h:36 +Timestamp 85 ; from /home/oms/LOFAR/autoconf_share/../CEP/CPA/OCTOPUSSY/src/OCTOPUSSY.aidlist:54 diff --git a/CEP/CPA/OCTOPUSSY/test/test_glish.cc b/CEP/CPA/OCTOPUSSY/test/test_glish.cc new file mode 100644 index 0000000000000000000000000000000000000000..c7df7bab9551cc0e39760fac3e722e8b230d8e8c --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/test/test_glish.cc @@ -0,0 +1,33 @@ +#include "Dispatcher.h" +#include "EchoWP.h" +#include "Glish/GlishClientWP.h" +#include "LoggerWP.h" +#include <sys/types.h> +#include <unistd.h> + +static int dum = aidRegistry_Testing(); + +int main (int argc,const char *argv[]) +{ + Debug::initLevels(argc,argv); + OctopussyConfig::initGlobal(argc,argv); + + try + { + Dispatcher dsp; + dsp.attach(makeGlishClientWP(argc,argv),DMI::ANON); + dsp.attach(new LoggerWP(10,Message::GLOBAL),DMI::ANON); + dsp.attach(new EchoWP(0),DMI::ANON); + dsp.start(); + dsp.pollLoop(); + dsp.stop(); + } + catch( Debug::Error err ) + { + cerr<<"\nCaught exception:\n"<<err.what()<<endl; + return 1; + } + cerr<<"Exiting normally\n"; + return 0; +} + diff --git a/CEP/CPA/OCTOPUSSY/test/test_gw.cc b/CEP/CPA/OCTOPUSSY/test/test_gw.cc new file mode 100644 index 0000000000000000000000000000000000000000..182f3ab772e26d96fa854b9da3b6a9fe912ed514 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/test/test_gw.cc @@ -0,0 +1,34 @@ +#include "Dispatcher.h" +#include "EchoWP.h" +#include "Gateways.h" +#include "GWClientWP.h" +#include "LoggerWP.h" +#include <sys/types.h> +#include <unistd.h> + +static int dum = aidRegistry_Testing(); + +int main (int argc,const char *argv[]) +{ + Debug::initLevels(argc,argv); + OctopussyConfig::initGlobal(argc,argv); + + try + { + Dispatcher dsp; + dsp.attach(new LoggerWP(10,Message::LOCAL),DMI::ANON); + dsp.attach(new EchoWP(-1),DMI::ANON); + initGateways(dsp); + dsp.start(); + dsp.pollLoop(); + dsp.stop(); + } + catch( Debug::Error err ) + { + cerr<<"\nCaught exception:\n"<<err.what()<<endl; + return 1; + } + cerr<<"Exiting normally\n"; + return 0; +} + diff --git a/CEP/CPA/OCTOPUSSY/test/test_gw0.cc b/CEP/CPA/OCTOPUSSY/test/test_gw0.cc new file mode 100644 index 0000000000000000000000000000000000000000..483c62916fd143838fc89d3de7162524eee1c7b2 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/test/test_gw0.cc @@ -0,0 +1,32 @@ +#include "Dispatcher.h" +#include "Gateways.h" +#include "LoggerWP.h" +#include <sys/types.h> +#include <unistd.h> + +int aidRegistry_Testing(); +static int dum = aidRegistry_Testing(); + +int main (int argc,const char *argv[]) +{ + Debug::initLevels(argc,argv); + OctopussyConfig::initGlobal(argc,argv); + + try + { + Dispatcher dsp; + dsp.attach(new LoggerWP(10,Message::LOCAL),DMI::ANON); + initGateways(dsp); + dsp.start(); + dsp.pollLoop(); + dsp.stop(); + } + catch( Debug::Error err ) + { + cerr<<"\nCaught exception:\n"<<err.what()<<endl; + return 1; + } + cerr<<"Exiting normally\n"; + return 0; +} + diff --git a/CEP/CPA/OCTOPUSSY/test/test_octopussy.cc b/CEP/CPA/OCTOPUSSY/test/test_octopussy.cc new file mode 100644 index 0000000000000000000000000000000000000000..19f80bd4cf3b086f58be1593c86a7fb3b8ba6e8e --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/test/test_octopussy.cc @@ -0,0 +1,33 @@ +#include "Dispatcher.h" +#include "EchoWP.h" +#include "GWServerWP.h" +#include "LoggerWP.h" +#include <sys/types.h> +#include <unistd.h> + +static int dum = aidRegistry_Testing(); + +int main (int argc,const char *argv[]) +{ + Debug::initLevels(argc,argv); + Debug::initLevels(argc,argv); + + try + { + Dispatcher dsp; + dsp.attach(new LoggerWP,DMI::ANON); + dsp.attach(new EchoWP,DMI::ANON); + dsp.attach(new EchoWP(5),DMI::ANON); + dsp.start(); + dsp.pollLoop(); + dsp.stop(); + } + catch( Debug::Error err ) + { + cerr<<"\nCaught exception:\n"<<err.what()<<endl; + return 1; + } + cerr<<"Exiting normally\n"; + return 0; +} + diff --git a/CEP/CPA/OCTOPUSSY/test/test_ping.cc b/CEP/CPA/OCTOPUSSY/test/test_ping.cc new file mode 100644 index 0000000000000000000000000000000000000000..de0c1ff3174e09a6277007da2117b8ee7faf57f7 --- /dev/null +++ b/CEP/CPA/OCTOPUSSY/test/test_ping.cc @@ -0,0 +1,33 @@ +#include "Dispatcher.h" +#include "EchoWP.h" +#include "GWServerWP.h" +#include "LoggerWP.h" +#include <sys/types.h> +#include <unistd.h> + +static int dum = aidRegistry_Testing(); + +int main (int argc,const char *argv[]) +{ + Debug::initLevels(argc,argv); + OctopussyConfig::initGlobal(argc,argv); + + try + { + Dispatcher dsp; + dsp.attach(new LoggerWP,DMI::ANON); + dsp.attach(new EchoWP(-1),DMI::ANON); + dsp.attach(new EchoWP(0),DMI::ANON); + dsp.start(); + dsp.pollLoop(); + dsp.stop(); + } + catch( Debug::Error err ) + { + cerr<<"\nCaught exception:\n"<<err.what()<<endl; + return 1; + } + cerr<<"Exiting normally\n"; + return 0; +} +