X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=PPI%2FConnectors.hh;h=52663cc5b5289b8cc3cbaca6ac40da418bc6736c;hb=ea8b2923c29a6902f507db2b485a44a58e9406f0;hp=6a87a3da33b6b511c1693d76eb3ce2da88877b30;hpb=f73fa16ed5abdce272ac77f8b8b9ef2b9922c266;p=senf.git diff --git a/PPI/Connectors.hh b/PPI/Connectors.hh index 6a87a3d..52663cc 100644 --- a/PPI/Connectors.hh +++ b/PPI/Connectors.hh @@ -1,3 +1,5 @@ +// $Id$ +// // Copyright (C) 2007 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY @@ -64,9 +66,36 @@ namespace connector { 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() + senf::ppi::connect() \n \ref ppi_connectors */ @@ -160,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_; @@ -185,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 @@ -325,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 safe_bool + public safe_bool { public: - PassiveInput(); - - ActiveOutput & peer() const; + GenericActiveOutput & peer() const; bool boolean_test() const; ///< \c true, if ! empty() @@ -350,6 +377,9 @@ namespace connector { \param[in] disc New queueing discipline */ + protected: + GenericPassiveInput(); + private: void v_enqueueEvent(); void v_dequeueEvent(); @@ -360,51 +390,169 @@ namespace connector { /** \brief Combination of PassiveConnector and OutputConnector */ - class PassiveOutput + class GenericPassiveOutput : public PassiveConnector, public OutputConnector, - public safe_bool + 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 safe_bool + 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 safe_bool + 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////////////////////////////////////////