X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=PPI%2FConnectors.hh;h=52663cc5b5289b8cc3cbaca6ac40da418bc6736c;hb=ea8b2923c29a6902f507db2b485a44a58e9406f0;hp=f2e94aaad24600815d48b09b90efcee9780de28c;hpb=410b5d6536361b7a7376c38efee92263e793fea4;p=senf.git diff --git a/PPI/Connectors.hh b/PPI/Connectors.hh index f2e94aa..52663cc 100644 --- a/PPI/Connectors.hh +++ b/PPI/Connectors.hh @@ -1,6 +1,8 @@ +// $Id$ +// // Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify @@ -28,7 +30,7 @@ #include #include #include -#include "../Utils/SafeBool.hh" +#include "../Utils/safe_bool.hh" #include "../Packets/Packets.hh" #include "predecl.hh" #include "detail/Callback.hh" @@ -55,8 +57,46 @@ namespace connector { All passive connectors call some onRequest callback whenever I/O needs to be performed. All input modules possess a packet queue. - We therefore have 4 connector types: senf::ppi::ActiveInput, senf::ppi::ActiveOutput, - senf::ppi::PassiveInput and senf::ppi::PassiveOutput. + We therefore have 4 connector types: + \li senf::ppi::connector::ActiveInput + \li senf::ppi::connector::ActiveOutput + \li senf::ppi::connector::PassiveInput + \li senf::ppi::connector::PassiveOutput. + + Connectors are declared as module data members and are then externally connected to other + modules. + + The connectors each take an optional template argument. If this argument is specified, it + must be the type of packet expected or sent on this connector. If it is not specified, + packets will be passed using the generic Packet handle. + + \code + class IpFilter : public senf::ppi::module::Module + { + SENF_PPI_MODULE(SomeModule); + + public: + senf::ppi::connector::ActiveInput input; + senf::ppi::connector::PassiveOutput output; + + IpFilter() { + route(input, output); + input.onRequest(&IpFilter::onRequest); + } + + private: + void onRequest() { + // 'input()' will return a senf::EthernetPacket packet handle + try { output( input().find() ); } + catch (senf::InvalidPacketChainException & ex) { ; } + } + }; + \endcode + + \see + senf::ppi::module::Module \n + senf::ppi::connect() \n + \ref ppi_connectors */ /** \brief Connector base-class @@ -149,7 +189,7 @@ namespace connector { // called by ForwardingRoute to register a new route void registerRoute(ForwardingRoute & route); - typedef detail::Callback<>::type Callback; + typedef ppi::detail::Callback<>::type Callback; Callback callback_; bool remoteThrottled_; @@ -174,7 +214,7 @@ namespace connector { class ActiveConnector : public virtual Connector { - typedef detail::Callback<>::type Callback; + typedef ppi::detail::Callback<>::type Callback; public: template void onThrottle(Handler handler); ///< Register throttle notification handler @@ -255,6 +295,7 @@ namespace connector { typedef Queue::const_iterator queue_iterator; ///< Iterator type of the embedded queue typedef Queue::size_type size_type; ///< Unsigned type for counting queue elements + Packet operator()(); ///< Get a packet /**< This member is the primary method to access received data. On passive connectors, this operator will just @@ -265,6 +306,8 @@ namespace connector { logic error in the module implementation and an exception is raised. */ + Packet read(); ///< Alias for operator()() + OutputConnector & peer() const; queue_iterator begin() const; ///< Access queue begin (head) @@ -299,7 +342,9 @@ namespace connector { : public virtual Connector { public: - void operator()(Packet p); ///< Send out a packet + void operator()(Packet p); ///< Send out a packet + + void write(Packet p); ///< Alias for operator()(Packet p) InputConnector & peer() const; @@ -309,21 +354,19 @@ namespace connector { /** \brief Combination of PassiveConnector and InputConnector - The PassiveInput automatically controls the connectors throttling state using a queueing - discipline. The standard queueing discipline is ThresholdQueueing, which throttles the - connection whenever the queue length reaches the high threshold and unthrottles the + The GenericPassiveInput automatically controls the connectors throttling state using a + queueing discipline. The standard queueing discipline is ThresholdQueueing, which throttles + the connection whenever the queue length reaches the high threshold and unthrottles the connection when the queue reaches the low threshold. The default queueing discipline is ThresholdQueueing(1,0) which will throttle the input whenever the queue is non-empty. */ - class PassiveInput + class GenericPassiveInput : public PassiveConnector, public InputConnector, - public SafeBool + public safe_bool { public: - PassiveInput(); - - ActiveOutput & peer() const; + GenericActiveOutput & peer() const; bool boolean_test() const; ///< \c true, if ! empty() @@ -334,6 +377,9 @@ namespace connector { \param[in] disc New queueing discipline */ + protected: + GenericPassiveInput(); + private: void v_enqueueEvent(); void v_dequeueEvent(); @@ -344,51 +390,169 @@ namespace connector { /** \brief Combination of PassiveConnector and OutputConnector */ - class PassiveOutput + class GenericPassiveOutput : public PassiveConnector, public OutputConnector, - public SafeBool + public safe_bool { public: - ActiveInput & peer() const; + GenericActiveInput & peer() const; bool boolean_test() const; ///< Always \c true - void connect(ActiveInput & target); ///< Internal: Use senf::ppi::connect() instead + void connect(GenericActiveInput & target); ///< Internal: Use senf::ppi::connect() instead + + friend class GenericActiveInput; + + protected: + GenericPassiveOutput(); - friend class ActiveInput; }; /** \brief Combination of ActiveConnector and InputConnector */ - class ActiveInput + class GenericActiveInput : public ActiveConnector, public InputConnector, - public SafeBool + public safe_bool { public: - PassiveOutput & peer() const; + GenericPassiveOutput & peer() const; bool boolean_test() const; ///< \c true, if ! empty() or ! throttled() void request(); ///< request more packets without dequeuing any packet + protected: + GenericActiveInput(); + private: void v_requestEvent(); }; /** \brief Combination of ActiveConnector and OutputConnector */ - class ActiveOutput + class GenericActiveOutput : public ActiveConnector, public OutputConnector, - public SafeBool + public safe_bool { public: - PassiveInput & peer() const; + GenericPassiveInput & peer() const; bool boolean_test() const; ///< \c true if peer() is ! throttled() - void connect(PassiveInput & target); ///< Internal: Use senf::ppi::connect() instead + void connect(GenericPassiveInput & target); ///< Internal: Use senf::ppi::connect() instead + + protected: + GenericActiveOutput(); + }; +#ifndef DOXYGEN + +# define TypedConnector_Input read +# define TypedConnector_Output write +# define TypedConnector(type, dir) \ + template \ + class type ## dir \ + : public Generic ## type ## dir, \ + private detail::Typed ## dir ## Mixin, PacketType> \ + { \ + typedef detail::Typed ## dir ## Mixin, PacketType> mixin; \ + public: \ + using mixin::operator(); \ + using mixin::TypedConnector_ ## dir ; \ + }; \ + template <> \ + class type ## dir : public Generic ## type ## dir \ + {} + + TypedConnector( Passive, Input ); + TypedConnector( Passive, Output ); + TypedConnector( Active, Input ); + TypedConnector( Active, Output ); + +# undef TypedConnector +# undef TypedConnector_Input +# undef TypedConnector_Output + +#else + + /** \brief Connector actively reading packets + + The ActiveInput connector template reads data actively from a connected module. This class + is completely implemented via it's base-class, GenericActiveInput, the only difference is + that read packets are returned as \a PacketType instead of generic senf::Packet references. + + \see GenericActiveInput \n + senf::ppi::connectro + */ + template + class ActiveInput : public GenericActiveInput + { + public: + PacketType operator()(); ///< Read packet + /**< \throws std::bad_cast, if the connector receives a + Packet which is not of type \a PacketType. + \returns newly read packet reference. */ + PacketType read(); ///< Alias for operator() + }; + + /** \brief Connector passively receiving packets + + The PassiveInput connector template receives packets sent to it from a connected + module. This class is completely implemented via it's base-class, GenericPassiveInput, the + only difference is that read packets are returned as \a PacketType instead of generic + senf::Packet references. + + \see GenericPassiveInput \n + senf::ppi::connector + */ + template + class PassiveInput : public GenericPassiveInput + { + public: + PacketType operator()(); ///< Read packet + /**< \throws std::bad_cast, if the connector receives a + Packet which is not of type \a PacketType. + \returns newly read packet reference. */ + PacketType read(); ///< Alias for operator() + }; + + /** \brief Connector actively sending packets + + The ActiveOutput connector template sends data actively to a connected module. This class is + completely implemented via it's base-class, GenericActiveOutput, the only difference is that + it only sends packets of type \a PacketType. + + \see GenericActiveOutput \n + senf::ppi::connector + */ + template + class ActiveOutput : public GenericActiveOutput + { + public: + PacketType operator()(); + PacketType write(); + }; + + /** \brief Connector passively providing packets + + The PassiveOutput connector template provides data passively to a connected module whenever + signaled. This class is completely implemented via it's base-class, GenericPassiveOutput, the + only difference is that it only sends packets of type \a PacketType. + + \see GenericPassiveOutput \n + senf::ppi::connector + */ + template + class PassiveOutput : public GenericPassiveOutput + { + public: + PacketType operator()(); + PacketType write(); + }; + +#endif + }}} ///////////////////////////////hh.e////////////////////////////////////////