namespace ppi {
namespace module {
+ /** \brief Adapter to connect passive connectors
+
+ ActiveFeeder is an adapter module which allows to connect to passive connectors. As long as
+ none of the connectors is throttled, the ActiveFeeder will forward packets from it's input
+ to it's output.
+
+ \note For this Module to work correctly, it is very important for the connectors to be
+ correctly throttled. Otherwise the system might well hang in an endless loop.
+ */
class ActiveFeeder
: public Module
{
namespace ppi {
namespace connector {
- /** \brief Connector baseclass
+ /** \namespace senf::ppi::connector
+ \brief Connector classes
+ */
+
+ /** \brief Connector base-class
This connector provides access to the generic connector facilities. This includes the
connection management (access to the connected peer) and the containment management (access
friend class module::Module;
};
- /** \brief Passive connector baseclass
+ /** \brief Passive connector base-class
A passive connector is a connector which is activated externally whenever an I/O request
occurs. Passive connectors are the origin of throttling notifications. Depending on the type
private:
// Called by the routing to change the remote throttling state
- void notifyThrottle(); ///< Forward a throttling notification to this connector
- void notifyUnthrottle(); ///< Forward an unthrottling notification to this connector
+ void notifyThrottle(); ///< Forward a throttle notification to this connector
+ void notifyUnthrottle(); ///< Forward an unthrottle notification to this connector
// Internal members to emit throttling notifications
void emitThrottle();
friend class senf::ppi::ForwardingRoute;
};
- /** \brief Active connector baseclass
+ /** \brief Active connector base-class
An active connector is a connector which emits I/O requests. Active connectors receive
throttling notifications. Depending on the type of connector (input or output) the
friend class PassiveConnector;
};
- /** \brief Input connector baseclass
+ /** \brief Input connector base-class
An input connector receives packets. It may be either an ActiveConnector or a
PassiveConnector. An input connector contains a packet queue. This queue enables processing
insertion/removal properties on both ends.
So probably we will use a deque. I'd like a container which keeps iterators intact on
- isertion/deletion but I believe that list is just to expensive since every packet will
+ insertion/deletion but I believe that list is just to expensive since every packet will
be added to the queue before it can be processed.
*/
class InputConnector
friend class OutputConnector;
};
- /** \brief Output connector baseclass
+ /** \brief Output connector base-class
An output connector sends out packets. It may be either an ActiveConnector or a
PassiveConnector. An output connector does \e not have an built-in queueing, it relies on
namespace senf {
namespace ppi {
- /** \brief
+ /** \brief Manually triggered event
+
+ DebugEvent is a manually triggered event. The event is triggered by explicit calls to
+ trigger() and not by the event infrastructure.
*/
class DebugEvent
: public EventImplementation<>
///@}
///////////////////////////////////////////////////////////////////////////
- void trigger();
+ void trigger(); ///< Trigger event
protected:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief DebugModules inline template implementation */
+
+//#include "DebugModules.ih"
+
+// Custom includes
+#include "Utils/hexdump.hh"
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::ppi::module::debug::LogWriter<Stream,Area,level>
+
+template <class Stream, class Area, senf::log::Level level>
+prefix_ senf::ppi::module::debug::LogWriter<Stream,Area,level>::LogWriter()
+{
+ noroute(input);
+ input.onRequest(&LogWriter::request);
+}
+
+////////////////////////////////////////
+// private members
+
+template <class Stream, class Area, senf::log::Level level>
+prefix_ void senf::ppi::module::debug::LogWriter<Stream,Area,level>::request()
+{
+ Packet packet (input());
+ SENF_LOG_BLOCK((Stream)(Area)(level)({
+ packet.dump(log);
+ hexdump(packet.last().data().begin(), packet.last().data().end(),log);
+ }));
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
#include "Packets/Packets.hh"
#include "Module.hh"
#include "ActiveFeeder.hh"
+#include "Utils/Logger.hh"
//#include "DebugModules.mpp"
///////////////////////////////hh.p////////////////////////////////////////
-/** \namespace senf::ppi::module::debug
- \brief Debug modules
-
- This namespace collects several modules helpful for PPI debugging. The modules allow to manually
- pass packets into a network and read back the output packets.
-
-
- */
-
namespace senf {
namespace ppi {
namespace module {
namespace debug {
- /** \brief
+ /** \namespace senf::ppi::module::debug
+ \brief Debug modules
+
+ This namespace collects several modules helpful for PPI debugging. The modules allow to
+ manually pass packets into a network and read back the output packets.
+
+ There are three categories of modules:
+
+ \li <i>Active modules</i> (ActiveSource, ActiveSink) are triggered by external
+ calls. Calling \c submit() / \c request() will send the request into the module network
+ synchronously. From this it follows, that senf::ppi::run() should \e not be
+ called. Instead senf::ppi::init() is used to initialize the network and explicit calls
+ to the active debug modules drive the execution.
+ \li <i>Passive modules</i> (PassiveSource, PassiveSink) contain a queue to save packets
+ (either packets to be transmitted or packets received) and are driven by the network.
+ \li <i>Feeder (almost-)modules</i> (ActiveFeederSource, ActiveFeederSink) are a hybrid of
+ both types of modules: They contain a packet queue but actively drive the network and
+ are used together with senf::ppi::run(). senf::ppi::run() will automatically terminate
+ if all available packets have been processed. These are not modules, they are
+ collections combining a passive debug module and a senf::ppi::ActiveFeeder.
+ */
+
+ /** \brief Debug packet source with active output
+
+ This module provides packets into the network. Each call to submit() will process the packet
+ synchronously.
+
+ \note This module should not be used together with senf::ppi::run(). Instead use
+ senf::ppi::init() and explicit submit() calls. It follows, that <em>no events will be
+ signaled in the network</em>.
*/
class ActiveSource
: public Module,
ActiveSource();
- void submit(Packet packet);
+ void submit(Packet packet); ///< Submit packet
+ /**< \pre boolean_test() is \c true */
- bool boolean_test() const;
+ bool boolean_test() const; ///< \c true if \a output is not throttled
};
+ /** \brief Debug packet source with passive output
+
+ This module provides a queue of packets for reading by the network. Each submit() call adds
+ a packet to the queue which will be sent into the network when requested. The output is
+ automatically throttled when the queue becomes empty.
+ */
class PassiveSource
: public Module
{
public:
typedef Queue::size_type size_type;
- PassiveSource();
-
connector::PassiveOutput output;
+
+ PassiveSource();
- void submit(Packet packet);
+ void submit(Packet packet); ///< Enqueue packet
- bool empty();
- size_type size();
+ bool empty(); ///< \c true if queue is empty
+ size_type size(); ///< Number of packets in queue
private:
void request();
Queue packets_;
};
+
+ /** \brief Debug packet sink with active input
+ This module requests packets from the network. Each call to request() will pass a packet
+ request into the network.
+
+ \note This module should not be used together with senf::ppi::run(). Instead use
+ senf::ppi::init() and explicit request() calls. It follows, that <em>no events will be
+ signaled in the network</em>.
+ */
class ActiveSink
: public Module,
public SafeBool<ActiveSink>
ActiveSink();
- Packet request();
+ Packet request(); ///< Request packet
+ /**< \pre boolean_test() is \c true */
- bool boolean_test() const;
+ bool boolean_test() const; ///< \c true, if \a input is not throttled
};
+ /** \brief Debug packet sink with passive input
+
+ This module provides a queue for the network to write packets into. The packets can then
+ later be analyzed.
+ */
class PassiveSink
: public Module
{
PassiveSink();
- bool empty();
- size_type size();
- iterator begin();
- iterator end();
+ bool empty(); ///< \c true, if queue is empty
+ size_type size(); ///< number of packets in the queue
+ iterator begin(); ///< begin iterator of packets in the queue
+ iterator end(); ///< past-the-end iterator of packets in the queue
- Packet front();
- Packet pop_front();
+ Packet front(); ///< first packet in the queue
+ Packet pop_front(); ///< remove and return first packet in the queue
- void clear();
+ void clear(); ///< clear the queue
private:
void request();
Queue packets_;
};
+ /** \brief Active, queue-based packet source
+
+ The ActiveFeederSource contains a packet queue containing the packets to be precessed. These
+ packets are actively fed into the network when it is run with senf::ppi::run() until it is
+ empty, when senf::ppi::run() will return.
+
+ \note senf::ppi::run will return as soon as no events are active. If want you want is to
+ precess a set of packets placed into the ActiveFeederSource queue you must make sure,
+ that eventually all events in the module are disabled by throttling or other
+ activities. Otherwise, senf::ppi::run() will \e not return.
+
+ ActiveFeederSource is not a module but a collection of two modules: a PassiveSource and an
+ ActiveFeeder.
+ */
class ActiveFeederSource
{
private:
ActiveFeederSource();
- void submit(Packet packet);
- bool empty();
- size_type size();
+ void submit(Packet packet); ///< enqueue packet
+ bool empty(); ///< \c true, if queue is empty
+ size_type size(); ///< number of packets in the queue
};
+ /** \brief Active, queue-based packet sink
+
+ The ActiveFeederSink contains a packet queue to receive the packets from the network. The
+ ActiveFeederSink will actively request packets from the network until it's input is
+ throttled.
+
+ \note ActiveFeederSink does \e not have a termination condition like ActiveFeederSource, it
+ relies on the network to throttle it's input. Also, the same not as for
+ ActiveFeederSource applies here too: You need to ensure, that no events are active
+ eventually or senf::ppi::run will not return.
+
+ ActiveFeederSink is not a module but a collection of two modules: a PassiveSink and an
+ ActiveFeeder.
+ */
class ActiveFeederSink
{
private:
void clear();
};
+
+ /** \brief Log received packets
+
+ This module will log all packets sent to it's input using SENF_LOG to the given log
+ \a Stream, \a Area and \a level.
+ */
+ template < class Stream = log::Debug,
+ class Area = log::DefaultArea,
+ senf::log::Level level = log::VERBOSE >
+ class LogWriter
+ : public module::Module
+ {
+ SENF_PPI_MODULE(LogWriter);
+ public:
+
+ connector::PassiveInput input;
+
+ LogWriter();
+
+ private:
+ void request();
+ };
}}}}
///////////////////////////////hh.e////////////////////////////////////////
#include "DebugModules.cci"
//#include "DebugModules.ct"
-//#include "DebugModules.cti"
+#include "DebugModules.cti"
#endif
\f
//#include "DebubgModules.test.hh"
//#include "DebubgModules.test.ih"
+
// Custom includes
#include <algorithm>
+#include <sstream>
+
+#define _senf_LOG_STREAM logstream
+namespace {
+ std::stringstream logstream;
+}
+
#include "Packets/Packets.hh"
#include "DebugModules.hh"
#include "Setup.hh"
debug::PassiveSink sink;
ppi::connect(source,sink);
-
source.submit(senf::DataPacket::create());
-
ppi::run();
BOOST_CHECK( source.empty() );
debug::ActiveFeederSink sink;
ppi::connect(source,sink);
-
source.submit(senf::DataPacket::create());
-
ppi::run();
BOOST_CHECK( ! sink.empty() );
BOOST_CHECK( source.empty() );
}
+BOOST_AUTO_UNIT_TEST(logWriter)
+{
+ debug::ActiveFeederSource source;
+ debug::LogWriter<> sink;
+
+ ppi::connect(source,sink);
+ senf::PacketData::byte data[] = { 0x13u, 0x24u, 0x35u };
+ source.submit( senf::DataPacket::create(data) );
+ senf::ppi::run();
+
+ BOOST_CHECK_EQUAL( logstream.str(),
+ " 0000 13 24 35 .$5\n\n" );
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
namespace senf {
namespace ppi {
- /** \brief
+ /** \brief Event registry and control
+
+ The EventManager control event registration and manages global event parameters. The
+ EventManager controls event dispatch but does \e not control event generation. This is the
+ responsibility of an external component (the Scheduler)
*/
class EventManager
{
///////////////////////////////////////////////////////////////////////////
// Types
- template <class Descriptor>
#ifndef DOXYGEN
+ // Somehow doxygen barfs on this definition
+ template <class Descriptor>
struct Callback
-#else
- // This is SO stupid but doxygen must have some scoping problems if the
- // struct is called 'Callback' and will hang in an endless loop somewhere
- struct Callback_
-#endif
: public detail::Callback<typename Descriptor::EventArg>
{};
+#endif
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@}
///////////////////////////////////////////////////////////////////////////
+ ClockService::clock_type now(); ///< Current time at last event dispatch
+ ClockService::clock_type time(); ///< Expected time of the last event
+
+ protected:
+
+ private:
template <class Descriptor>
void registerEvent(module::Module & module,
typename Callback<Descriptor>::type callback,
Descriptor & descriptor);
- ClockService::clock_type now();
- ClockService::clock_type time();
-
- protected:
-
- private:
void destroyModule(module::Module & module);
typedef boost::ptr_vector<detail::EventBindingBase> EventRegistrations;
// 'callback()' will access the EventBinding wrapper to find the user-callback to signal. It
// will do any needed internal processing, call that user callback and clean up afterwards.
- /** \brief Generic event interface baseclass
+ /** \brief Generic event interface base-class
- The EventDescriptor baseclass provides an interface to manipulate events in a generic
- way. This allows to register events or to temporarily disable event processing.
+ The EventDescriptor base-class provides an interface to control events.
*/
class EventDescriptor
{
friend class ForwardingRoute;
};
+ /** \brief Internal: Callback forwarders
+ */
template <class EventType, class Self>
class EventImplementationHelper
{
typedef typename detail::EventArgType<EventType>::type EventArg;
void callback(EventArg event, ClockService::clock_type time);
- void callback(EventArg event);
+ ///< Forward event to user callback
+ /**< \param[in] event Event argument to pass to the user
+ callback
+ \param[in] time Expected time of the event */
+ void callback(EventArg event); ///< Forward event to user callback
+ /**< \param[in] event Event argument to pass to the user
+ callback. */
private:
detail::EventBinding<EventType> & binding();
#endif
+ /** \brief Event implementation base class
+
+ EventImplementation provides the base-class for all Event implementations.
+ \code
+ class SomeEvent : public EventImplementation<SomeEventArg>
+ {
+ public:
+ SomeEvent() {}
+
+ private:
+ virtual void v_enable() {
+ // register cb() to be called when the event occurs
+ }
+
+ virtual void v_disable() {
+ // unregister cb()
+ }
+
+ void cb() {
+ // Build event argument
+ SomeEventArg arg (...);
+ // Call the event callback
+ callback(arg);
+ }
+ };
+ \endcode
+
+ Every event needs to implement v_enable() and v_disable(). v_enable() should register some
+ member (in the example \c cb() ) to be called whenever the event occurs, while v_disable()
+ should unregister it.
+
+ The \a EventType argument to EventImplementation defines the type of argument passed to the
+ user callback. It defaults to \c void. . This user callback is called from within the
+ registered member (e.g. \c cb() ) by calling the inherited callback() member. This member
+ takes an \a EventType reference as argument which will be forwarded to the user callback. If
+ available, you should also provide the \e expected event time as a second argument.
+ */
template <class EventType>
class EventImplementation
: public EventDescriptor,
typedef EventType Event;
typedef typename detail::EventArgType<EventType>::type EventArg;
- module::Module & module() const;
- EventManager & manager() const;
+ module::Module & module() const; ///< Module in which the event is registered
+ EventManager & manager() const; ///< EventManager of the event
protected:
EventImplementation();
namespace ppi {
namespace detail {
+#ifndef DOXYGEN
+
template <class EventType>
struct EventArgType
{
typedef EventType const & type;
};
-#ifndef DOXYGEN
-
template <>
struct EventArgType<void>
{
namespace senf {
namespace ppi {
+ /** \brief IOEvent event information
+
+ Information passed to the IOEvent event handler
+ */
struct IOEventInfo
{
- unsigned events;
+ unsigned events; ///< Type of event signaled
+ /**< The value is a combination of the flags from
+ IOEvent::EventFlags */
};
- /** \brief
+ /** \brief FileHandle based I/O read/write event
+
+ An IOEvent is signaled, whenever the FileHandle \a handle becomes readable or writable. The
+ type of event is specified using the \a events mask with values from EventFlags.
\fixme Implement error/EOF handling
*/
namespace senf {
namespace ppi {
+ /** \brief Continually signaled event
+
+ An IdleEvent is signaled continually and repeatedly while enabled. It will consume 100% of
+ available CPU resources. The resource usage is controlled by adequate event throttling.
+ */
class IdleEvent
: public EventImplementation<>
{
namespace senf {
namespace ppi {
+ /** \brief IntervalTimer event information
+
+ Information passed to the IntervalTimer event handler
+ */
struct IntervalTimerEventInfo
{
- ClockService::clock_type expected;
- ClockService::clock_type intervalStart;
- unsigned number;
+ ClockService::clock_type expected; ///< Scheduled event time
+ ClockService::clock_type intervalStart; ///< Start of the current time interval
+ unsigned number; ///< Number of the current event within the interval
};
- /** \brief
+ /** \brief High precision regularly signaled event.
+
+ An IntervalTimer signals an event \a eventsPerInterval times each \a interval
+ nanoseconds. The event counter and timer are reset, whenever the event is disabled.
*/
class IntervalTimer
: public EventImplementation<IntervalTimerEventInfo>
\section class_diagram Class Diagram
\image html classes.png
+
+ \fixme Implement Spliters: PassiveSplitter, PrioritySplitter, CloneSplitter
+ \fixme Implement DiscardSink, CloneSource
*/
\f
namespace ppi {
namespace module {
- /** \brief Module baseclass
+ /** \brief Module base-class
- senf::ppi::Module is the baseclass of all PPI modules. It provides the module implementation
+ senf::ppi::Module is the base-class of all PPI modules. It provides the module implementation
with interfaces to several PPI facilities:
\li Connector management
\li Event handling
To provide internal bookkeeping, most access to the PPI infrastructure is managed through
- this base class.
-
- Instances of this class may be allocated either statically or dynamically. Dynamic instances
- are automatically managed using the dynamicModule adaptor.
+ this base class. This is an example module specification:
+ \code
+ class SomeModule : public senf::ppi::module::Module
+ {
+ SENF_PPI_MODULE(SomeModule);
+
+ senf::FileHandle handle;
+
+ // If needed, define events
+ senf::ppi::IOEvent event;
+
+ public:
+ // Define connectors. Any number and type of connectors may be defined. Connectors
+ // must be public since they need to be accessed to connect modules with each other.
+ senf::ppi::connector::PassiveInput input;
+ senf::ppi::connector::ActiveOutput output;
+
+ SomeModule(senf::FileHandle h)
+ : handle ( h ),
+ event ( handle, senf::ppi::IOEvent::Read )
+ {
+ // Set up routing. If some connector is not routed you need to explicitly state this
+ // using noroute()
+ route( input, output );
+ route( event, output )
+ .autoThrottling( false );
+
+ // Register event handlers
+ registerEvent( &SomeModule::read, event );
+
+ // Register passive connector handlers
+ input.onRequest( &SomeModule::outputRequest );
+
+ // If needed, you may register throttling event handlers
+ output.onThrottle( &SomeModule::throttle );
+ output.onUnthrottle( &SomeModule::unthrottle );
+ }
+
+ void read() {
+ // Called whenever the 'handle' is readable. Read data, do processing and so
+ // on. This example reads the data, puts it into an ethernet packet and sends the
+ // packet out via the active output.
+ output(senf::EthernetPacket::create(handle.read()))
+ }
+
+ void outputRequest() {
+ // Called whenever a packet is sent into the input to. Here we just forward it to
+ // the output if it is an EthernetPacket
+ senf::EthernetPacket p (input().find<EthernetPacket>(senf::nothrow));
+ if (p)
+ output(p);
+ }
+
+ void onThrottle() {
+ // Called whenever a throttle notification comes in. Here, we just disable the
+ // event (which is stupid since we should just not have disabled autoThrottling on
+ // the route but this is only an example which tries to be simple ...)
+ event.disable();
+ }
+
+ void onUnthrottle() {
+ // and for unthrottle notifications
+ event.enable();
+ }
+
+ };
+ \endcode
+
+ If your module only has a single input connector, you should call this connector \c
+ input. If it has only a single output connector, you should call it \c output. This allows
+ to setup connections without stating the connector explicitly (see senf::ppi::connect()).
*/
class Module
: boost::noncopyable
callable object or it may be a member function pointer
pointing to a member function of the Module derived
classed. The handler may \e optionally take an Argument
- of type <tt>typename Descriptor::Event const
- &</tt>. This object allows to access detailed
- information on the event delivered.
+ of type <tt>Descriptor::Event const &</tt>. This object
+ allows to access detailed information on the event
+ delivered.
The \a descriptor describes the event to signal. This
event is signaled
\param[in] descriptor The type of event to register */
- ClockService::clock_type time() const; ///< Return timestamp of the currently processing
- ///< event
+ ClockService::clock_type time() const; ///< Time-stamp of the currently processing event
+ /**< If available, this returns the scheduled time of the
+ event. */
- ClockService::clock_type now() const;
+ ClockService::clock_type now() const; ///< Current time of the currently processing event
#ifndef DOXYGEN
virtual void macro_SENF_PPI_MODULE_missing() = 0;
namespace module {
namespace detail {
+#ifndef DOXYGEN
+
// Placing these into a class simplifies the friend declaration
template <class Source, class Target>
struct RouteHelper
EventDescriptor &,
connector::OutputConnector &);
};
+
+#endif
}}}}
(*i)->init();
}
+#ifndef DOXYGEN
+
struct senf::ppi::ModuleManager::RunGuard
{
RunGuard(ModuleManager & m) : manager(m) { manager.running_ = true; }
ModuleManager & manager;
};
+#endif
+
prefix_ void senf::ppi::ModuleManager::run()
{
init();
typedef std::vector<module::Module *> ModuleRegistry;
+#ifndef DOXYGEN
struct RunGuard;
friend class RunGuard;
+#endif
ModuleRegistry moduleRegistry_;
bool running_;
namespace senf {
namespace ppi {
+ /** \brief Routing base class
+
+ Routing information is defined within each module to define the control flow. RouteBase is
+ the generic base class for all routing entries.
+ */
class RouteBase
{
public:
module::Module * module_;
};
+ /** \brief Forwarding route base class
+
+ All routes which may forward control information are based on
+ ForwardingRoute. ForwardingRoute provides methods to control and query the throttling
+ behavior.
+ */
class ForwardingRoute
: public RouteBase
{
public:
- bool autoThrottling() const;
+ bool autoThrottling() const; ///< Query current autoThrottling state
void autoThrottling(bool state); ///< Change automatic throttle notification forwarding
/**< By default, throttle notifications are automatically
forwarded from active to passive connectors. This may
\param[in] state New throttle forwarding state */
- bool throttled() const;
+ bool throttled() const; ///< \c true, if the route is throttled
+ /**< This member checks only the automatic throttling
+ state. If autoThrottling() is \c false, this member
+ will always return \c false. */
protected:
ForwardingRoute(module::Module & module);
Route instances are created by Module::route statements. The Route class provides an
interface to manipulate the flow processing.
+
+ The concrete interface provided depends on the type of route. If the route is a forwarding
+ route, it will be based on ForwardingRoute otherwise it will be based directly on
+ RouteBase.
*/
template <class Source, class Target>
class Route
: public detail::RouteImplementation<Source,Target>
{
- typedef detail::RouteImplementation<Source,Target> Base;
private:
+ typedef detail::RouteImplementation<Source,Target> Base;
typedef detail::RouteImplementation<Source,Target> Implementation;
Route(module::Module & module, Source & source, Target & target);
///////////////////////////////ih.p////////////////////////////////////////
+#ifndef DOXYGEN
+
namespace senf {
namespace ppi {
namespace detail {
typedef Connector type;
};
-#ifndef DOXYGEN
-
// RoutingTraits specialization for Event types. Events may be both dataSource or dataTarget but
// cannot be notifySource.
template <class Event>
typedef EventDescriptor type;
};
-#endif
-
// The RoutingTraits give routing related information about the argument type:
// - Wether the type is a notifySource or notifyTarget
// - Wether the type is dataSource or dataTarget
}}}
+#endif
+
///////////////////////////////ih.e////////////////////////////////////////
#endif
class SomeReader
{
public:
- typedef unspecified_type Handle; // type of handle requested
- SomeReader(); // default constructible
- Packet::ptr operator()(Handle handle); // extraction function
+ typedef unspecified_type Handle; // type of handle requested
+ SomeReader(); // default constructible
+ Packet operator()(Handle handle); // extraction function
};
\endcode
+
+ Whenever the FileHandle object is ready for reading, the \a Reader's \c operator() is called
+ to read a packet. The default \a Reader is \c PacketReader<>, which will read packets from a
+ datagram SocketHandle into DataPacket's. You may
+
*/
template <class Reader=PacketReader<> >
class ActiveSocketReader
namespace ppi {
namespace detail {
+ /** \brief Internal: Association Event - Module - Handler, base-class */
class EventBindingBase
{
public:
friend class senf::ppi::EventManager;
};
+ /** \brief Internal: Callback forwarders
+ */
template <class EventType, class Self>
class EventBindingHelper
{
#endif
+ /** \brief Internal: Association Event - Module - Handler, event type specific */
template <class EventType>
class EventBinding
: public EventBindingBase,
class QueueingDiscipline;
class ModuleManager;
+#ifndef DOXYGEN
+
namespace detail {
class EventBindingBase;
template <class EvImpl> class EventBinding;
class RouteImplementation;
}
+#endif
+
namespace module {
class Module;
namespace detail {
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
+namespace log {
# ifndef _senf_LOG_STREAM
# define _senf_LOG_STREAM std::cerr
\hideinitializer
*/
-# define SENF_LOG_DEF_AREA(area)
+# define SENF_LOG_DEF_AREA(area) struct area {}
/** \brief Define log stream
\hideinitializer
*/
-# define SENF_LOG_DEF_STREAM(stream)
+# define SENF_LOG_DEF_STREAM(stream) struct stream {}
/** \brief Define log parameter alias
\hideinitializer
*/
-# define SENF_LOG_DEF_ALIAS(alias,args)
+# define SENF_LOG_DEF_ALIAS(alias,args) struct alias {}
/// @}
-}
+ enum Level { VERBOSE, NOTICE, MESSAGE, IMPORTANT, CRITICAL };
+
+ SENF_LOG_DEF_STREAM(Debug);
+ SENF_LOG_DEF_AREA(DefaultArea);
+
+}}
///////////////////////////////hh.e////////////////////////////////////////
//#include "Logger.cci"
acceptfrom
accessor
+ActiveConnector
+ActiveFeeder
+ActiveFeederSink
+ActiveFeederSource
+ActiveInput
+ActiveOutput
+ActiveSink
+ActiveSource
addr
AddressingPolicy
AddressingPolicyBase
addtogroup
aListCollection
alloc
+arg
async
+autoThrottling
aVectorCollection
BaseParser
berlios
bitfield
bund
-Callback
+callback
callbacks
cb
cerr
DataPacket
dd
de
+DebugModules
DefaultBundle
defaultInit
defgroup
+deque
dil
DNS
dontinclude
EthVLan
EUI
EUID
+EventBinding
+EventDescriptor
+EventImplementation
+EventManager
+eventsPerInterval
+EventType
ExampleListPolicy
ExampleVectorPolicy
ExtendedParser
fixme
fokus
FooParser
+ForwardingRoute
fraunhofer
fuer
GlobalScope
html
http
IANA
+IdleEvent
ih
impl
INet
initHeadSize
initSize
inline
+InputConnector
Institut
Int
+IntervalTimer
IntField
InvalidPacketChainException
+IOEvent
ip
IpV
ipv
NIS
NoAddressingPolicy
noinit
+noroute
nothrow
offene
Ok
+onRequest
+onThrottle
+onUnthrottle
Ooops
org
os
ostream
OtherPacket
OtherPacketType
+OutputConnector
+outputRequest
OverlayField
PacketData
PacketImpl
ParseListN
parseNextAs
ParseVec
+PassiveConnector
+PassiveInput
+PassiveOutput
+PassiveSink
+PassiveSource
png
+ppi
pre
prev
protocolbundle
protocolbundles
+QueueingDiscipline
+queueSize
refcount
+registerEvent
registerPacket
registerPacketType
registerSomePacket
SizeParser
skipline
SocketHandle
+SomeEvent
+SomeEventArg
someField
+SomeModule
someOtherField
SomePacket
SomePacketParser
SystemException
td
templated
+ThresholdQueueing
todo
tr
TruncatedPacketException
UInt
UIntField
unicast
+unthrottle
+unthrottles
+unthrottling
VectorN
vlanId
VLanId