SENF_PPI_MODULE(RateFilter);
public:
- connector::ActiveInput input;
- connector::ActiveOutput output;
+ connector::ActiveInput<> input;
+ connector::ActiveOutput<> output;
RateFilter(senf::ClockService::clock_type interval);
RateFilter rateFilter;
public:
- connector::PassiveInput & input;
- connector::ActiveOutput & output;
+ connector::PassiveInput<> & input;
+ connector::ActiveOutput<> & output;
RateStuffer(senf::ClockService::clock_type interval,
senf::Packet packet,
{
SENF_PPI_MODULE(ActiveFeeder);
public:
- connector::ActiveInput input;
- connector::ActiveOutput output;
+ connector::ActiveInput<> input;
+ connector::ActiveOutput<> output;
ActiveFeeder();
SENF_PPI_MODULE(CloneSource);
public:
- connector::PassiveOutput output;
+ connector::PassiveOutput<> output;
CloneSource(senf::Packet packet);
void replacePacket(senf::Packet packet);
\brief Connectors non-inline non-template implementation */
#include "Connectors.hh"
-//#include "Connectors.ih"
+#include "Connectors.ih"
// Custom includes
#include "Route.hh"
{}
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::connector::ActiveInput
+// senf::ppi::connector::GenericActiveInput
////////////////////////////////////////
// private members
-prefix_ void senf::ppi::connector::ActiveInput::v_requestEvent()
+prefix_ void senf::ppi::connector::GenericActiveInput::v_requestEvent()
{
request();
}
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::connector::PassiveInput
+// senf::ppi::connector::GenericPassiveInput
////////////////////////////////////////
// private members
-prefix_ void senf::ppi::connector::PassiveInput::v_enqueueEvent()
+prefix_ void senf::ppi::connector::GenericPassiveInput::v_enqueueEvent()
{
emit();
qdisc_->update(*this, QueueingDiscipline::ENQUEUE);
}
-prefix_ void senf::ppi::connector::PassiveInput::v_dequeueEvent()
+prefix_ void senf::ppi::connector::GenericPassiveInput::v_dequeueEvent()
{
qdisc_->update(*this, QueueingDiscipline::DEQUEUE);
}
-prefix_ void senf::ppi::connector::PassiveInput::v_unthrottleEvent()
+prefix_ void senf::ppi::connector::GenericPassiveInput::v_unthrottleEvent()
{
size_type n (queueSize());
while (n) {
{}
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::connector::PassiveInput
+// senf::ppi::connector::GenericPassiveInput
-prefix_ senf::ppi::connector::PassiveInput::PassiveInput()
+prefix_ senf::ppi::connector::GenericPassiveInput::GenericPassiveInput()
: qdisc_(new ThresholdQueueing(1,0))
{}
-prefix_ senf::ppi::connector::ActiveOutput & senf::ppi::connector::PassiveInput::peer()
+prefix_ senf::ppi::connector::GenericActiveOutput & senf::ppi::connector::GenericPassiveInput::peer()
const
{
- return dynamic_cast<ActiveOutput&>(Connector::peer());
+ return dynamic_cast<GenericActiveOutput&>(Connector::peer());
}
-prefix_ bool senf::ppi::connector::PassiveInput::boolean_test()
+prefix_ bool senf::ppi::connector::GenericPassiveInput::boolean_test()
const
{
return ! empty();
}
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::connector::PassiveOutput
+// senf::ppi::connector::GenericPassiveOutput
-prefix_ senf::ppi::connector::ActiveInput & senf::ppi::connector::PassiveOutput::peer()
+prefix_ senf::ppi::connector::GenericActiveInput & senf::ppi::connector::GenericPassiveOutput::peer()
const
{
- return dynamic_cast<ActiveInput&>(Connector::peer());
+ return dynamic_cast<GenericActiveInput&>(Connector::peer());
}
-prefix_ bool senf::ppi::connector::PassiveOutput::boolean_test()
+prefix_ bool senf::ppi::connector::GenericPassiveOutput::boolean_test()
const
{
return true;
}
-prefix_ void senf::ppi::connector::PassiveOutput::connect(ActiveInput & target)
+prefix_ void senf::ppi::connector::GenericPassiveOutput::connect(GenericActiveInput & target)
{
Connector::connect(target);
}
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::connector::ActiveInput
+// senf::ppi::connector::GenericActiveInput
-prefix_ senf::ppi::connector::PassiveOutput & senf::ppi::connector::ActiveInput::peer()
+prefix_ senf::ppi::connector::GenericPassiveOutput & senf::ppi::connector::GenericActiveInput::peer()
const
{
- return dynamic_cast<PassiveOutput&>(Connector::peer());
+ return dynamic_cast<GenericPassiveOutput&>(Connector::peer());
}
-prefix_ bool senf::ppi::connector::ActiveInput::boolean_test()
+prefix_ bool senf::ppi::connector::GenericActiveInput::boolean_test()
const
{
return ! empty() || ! peer().throttled();
}
-prefix_ void senf::ppi::connector::ActiveInput::request()
+prefix_ void senf::ppi::connector::GenericActiveInput::request()
{
peer().emit();
}
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::connector::ActiveOutput
+// senf::ppi::connector::GenericActiveOutput
-prefix_ senf::ppi::connector::PassiveInput & senf::ppi::connector::ActiveOutput::peer()
+prefix_ senf::ppi::connector::GenericPassiveInput & senf::ppi::connector::GenericActiveOutput::peer()
const
{
- return dynamic_cast<PassiveInput&>(Connector::peer());
+ return dynamic_cast<GenericPassiveInput&>(Connector::peer());
}
-prefix_ bool senf::ppi::connector::ActiveOutput::boolean_test()
+prefix_ bool senf::ppi::connector::GenericActiveOutput::boolean_test()
const
{
return ! peer().throttled();
}
-prefix_ void senf::ppi::connector::ActiveOutput::connect(PassiveInput & target)
+prefix_ void senf::ppi::connector::GenericActiveOutput::connect(GenericPassiveInput & target)
{
Connector::connect(target);
}
/** \file
\brief Connectors inline template implementation */
-//#include "Connectors.ih"
+#include "Connectors.ih"
// Custom includes
///////////////////////////////cti.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
+// senf::ppi::connectors::detail::TypedInputMixin<Self,PacketType>
+
+template <class Self, class PacketType>
+prefix_ typename senf::ppi::connector::detail::TypedInputMixin<Self,PacketType>::Type
+senf::ppi::connector::detail::TypedInputMixin<Self,PacketType>::operator()()
+{
+ return static_cast<Self*>(this)->InputConnector::operator()().template as<Type>();
+}
+
+template <class Self, class PacketType>
+prefix_ typename senf::ppi::connector::detail::TypedInputMixin<Self,PacketType>::Type
+senf::ppi::connector::detail::TypedInputMixin<Self,PacketType>::read()
+{
+ return static_cast<Self*>(this)->InputConnector::read().template as<Type>();
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::ppi::connector::detail::TypedOutputMixin<Self,PacketType>
+
+template <class Self, class PacketType>
+prefix_ void senf::ppi::connector::detail::TypedOutputMixin<Self,PacketType>::operator()(Type p)
+{
+ static_cast<Self*>(this)->OutputConnector::operator()(p);
+}
+
+template <class Self, class PacketType>
+prefix_ void senf::ppi::connector::detail::TypedOutputMixin<Self,PacketType>::write(Type p)
+{
+ static_cast<Self*>(this)->OutputConnector::write(p);
+}
+
+///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::PassiveConnector
template <class Handler>
prefix_ void senf::ppi::connector::PassiveConnector::onRequest(Handler handler)
{
- callback_ = detail::Callback<>::make(handler, module());
+ callback_ = ppi::detail::Callback<>::make(handler, module());
}
///////////////////////////////////////////////////////////////////////////
template <class Handler>
prefix_ void senf::ppi::connector::ActiveConnector::onThrottle(Handler handler)
{
- throttleCallback_ = detail::Callback<>::make(handler, module());
+ throttleCallback_ = ppi::detail::Callback<>::make(handler, module());
}
template <class Handler>
prefix_ void senf::ppi::connector::ActiveConnector::onUnthrottle(Handler handler)
{
- unthrottleCallback_ = detail::Callback<>::make(handler, module());
+ unthrottleCallback_ = ppi::detail::Callback<>::make(handler, module());
}
///////////////////////////////////////////////////////////////////////////
-// senf::ppi::connector::PassiveInput
+// senf::ppi::connector::GenericPassiveInput
template <class QDisc>
-prefix_ void senf::ppi::connector::PassiveInput::qdisc(QDisc const & disc)
+prefix_ void senf::ppi::connector::GenericPassiveInput::qdisc(QDisc const & disc)
{
qdisc_.reset(new QDisc(disc));
}
// 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_;
class ActiveConnector
: public virtual Connector
{
- typedef detail::Callback<>::type Callback;
+ typedef ppi::detail::Callback<>::type Callback;
public:
template <class Handler>
void onThrottle(Handler handler); ///< Register throttle notification handler
/** \brief Combination of PassiveConnector and InputConnector
- The PassiveInput automatically controls the connectors throttling state using a queueing
+ 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
<tt>ThresholdQueueing(1,0)</tt> which will throttle the input whenever the queue is
non-empty.
*/
- class PassiveInput
+ class GenericPassiveInput
: public PassiveConnector, public InputConnector,
- public safe_bool<PassiveInput>
+ public safe_bool<GenericPassiveInput>
{
public:
- PassiveInput();
+ GenericPassiveInput();
- ActiveOutput & peer() const;
+ GenericActiveOutput & peer() const;
bool boolean_test() const; ///< \c true, if ! empty()
/** \brief Combination of PassiveConnector and OutputConnector
*/
- class PassiveOutput
+ class GenericPassiveOutput
: public PassiveConnector, public OutputConnector,
- public safe_bool<PassiveOutput>
+ public safe_bool<GenericPassiveOutput>
{
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 ActiveInput;
+ friend class GenericActiveInput;
};
/** \brief Combination of ActiveConnector and InputConnector
*/
- class ActiveInput
+ class GenericActiveInput
: public ActiveConnector, public InputConnector,
- public safe_bool<ActiveInput>
+ public safe_bool<GenericActiveInput>
{
public:
- PassiveOutput & peer() const;
+ GenericPassiveOutput & peer() const;
bool boolean_test() const; ///< \c true, if ! empty() or ! throttled()
/** \brief Combination of ActiveConnector and OutputConnector
*/
- class ActiveOutput
+ class GenericActiveOutput
: public ActiveConnector, public OutputConnector,
- public safe_bool<ActiveOutput>
+ public safe_bool<GenericActiveOutput>
{
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
};
+# define TypedConnector(Name, Mixin, dir) \
+ template <class PacketType> \
+ class Name \
+ : public Generic ## Name, detail::TypedInputMixin<Name<PacketType>, PacketType> \
+ { \
+ typedef detail::TypedInputMixin<Name<PacketType>, PacketType> mixin; \
+ public: \
+ using mixin::operator(); \
+ using mixin:: dir ; \
+ }; \
+ template <> \
+ class Name <Packet> \
+ : public Generic ## Name \
+ {}
+
+ TypedConnector(PassiveInput, TypedInputMixin, read);
+ TypedConnector(PassiveOutput, TypedOutputMixin, write);
+ TypedConnector(ActiveInput, TypedInputMixin, read);
+ TypedConnector(ActiveOutput, TypedOutputMixin, write);
+
+# undef TypedConnector
+
}}}
///////////////////////////////hh.e////////////////////////////////////////
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// 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 Connectors internal header */
+
+#ifndef IH_Connectors_
+#define IH_Connectors_ 1
+
+// Custom includes
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace senf {
+namespace ppi {
+namespace connector {
+namespace detail {
+
+ template <class Self, class PacketType>
+ class TypedInputMixin
+ {
+ public:
+ typedef PacketType Type;
+
+ Type operator()();
+ Type read();
+ };
+
+ template <class Self, class PacketType>
+ class TypedOutputMixin
+ {
+ public:
+ typedef PacketType Type;
+
+ void operator()(Type p);
+ void write(Type p);
+ };
+
+}}}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\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:
namespace {
- class PassiveInputTest
+ class GenericPassiveInputTest
: public ppi::module::Module
{
- SENF_PPI_MODULE(PassiveInputTest);
+ SENF_PPI_MODULE(GenericPassiveInputTest);
public:
- ppi::connector::PassiveInput input;
+ ppi::connector::GenericPassiveInput input;
- PassiveInputTest() : counter() {
+ GenericPassiveInputTest() : counter() {
noroute(input);
- input.onRequest(&PassiveInputTest::request);
+ input.onRequest(&GenericPassiveInputTest::request);
}
void request() {
BOOST_AUTO_UNIT_TEST(passiveInput)
{
debug::ActiveSource source;
- PassiveInputTest target;
+ GenericPassiveInputTest target;
ppi::connect(source,target);
ppi::init();
SENF_PPI_MODULE(ActiveSource);
public:
- connector::ActiveOutput output;
+ connector::ActiveOutput<> output;
ActiveSource();
public:
typedef Queue::size_type size_type;
- connector::PassiveOutput output;
+ connector::PassiveOutput<> output;
PassiveSource();
SENF_PPI_MODULE(ActiveSink);
public:
- connector::ActiveInput input;
+ connector::ActiveInput<> input;
ActiveSink();
typedef Queue::size_type size_type;
typedef Queue::const_iterator iterator;
- connector::PassiveInput input;
+ connector::PassiveInput<> input;
PassiveSink();
public:
typedef PassiveSource::size_type size_type;
- connector::ActiveOutput & output;
+ connector::ActiveOutput<> & output;
ActiveFeederSource();
typedef PassiveSink::size_type size_type;
typedef PassiveSink::iterator iterator;
- connector::ActiveInput & input;
+ connector::ActiveInput<> & input;
ActiveFeederSink();
SENF_PPI_MODULE(LogSink);
public:
- connector::PassiveInput input;
+ connector::PassiveInput<> input;
LogSink();
{
SENF_PPI_MODULE(DiscardSink);
public:
- connector::PassiveInput input;
+ connector::PassiveInput<> input;
DiscardSink();
////////////////////////////////////////
// private members
-prefix_ senf::ppi::connector::PassiveInput & senf::ppi::module::PassiveJoin::newInput()
+prefix_ senf::ppi::connector::GenericPassiveInput & senf::ppi::module::PassiveJoin::newInput()
{
- inputs_.push_back(new connector::PassiveInput());
- connector::PassiveInput & input (inputs_.back());
+ inputs_.push_back(new connector::GenericPassiveInput());
+ connector::GenericPassiveInput & input (inputs_.back());
noroute(input);
input.onRequest(boost::bind(&PassiveJoin::request,this,boost::ref(input)));
return input;
}
-prefix_ void senf::ppi::module::PassiveJoin::request(connector::PassiveInput & input)
+prefix_ void senf::ppi::module::PassiveJoin::request(connector::GenericPassiveInput & input)
{
output(input());
}
using boost::lambda::_1;
using boost::lambda::bind;
std::for_each(inputs_.begin(), inputs_.end(),
- bind(&connector::PassiveInput::throttle, _1));
+ bind(&connector::GenericPassiveInput::throttle, _1));
}
prefix_ void senf::ppi::module::PassiveJoin::onUnthrottle()
using boost::lambda::_1;
using boost::lambda::bind;
std::for_each(inputs_.begin(), inputs_.end(),
- bind(&connector::PassiveInput::unthrottle, _1));
+ bind(&connector::GenericPassiveInput::unthrottle, _1));
}
///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////
// private members
-prefix_ senf::ppi::connector::ActiveInput & senf::ppi::module::PriorityJoin::newInput()
+prefix_ senf::ppi::connector::GenericActiveInput & senf::ppi::module::PriorityJoin::newInput()
{
- inputs_.push_back(new connector::ActiveInput());
- connector::ActiveInput & input (inputs_.back());
+ inputs_.push_back(new connector::GenericActiveInput());
+ connector::GenericActiveInput & input (inputs_.back());
noroute(input);
input.onThrottle(&PriorityJoin::onThrottle);
using boost::lambda::_1;
using boost::lambda::bind;
Inputs::iterator i (std::find_if(inputs_.begin(), inputs_.end(),
- ! bind(&connector::ActiveInput::throttled, _1)));
+ ! bind(&connector::GenericActiveInput::throttled, _1)));
if (i != inputs_.end())
output((*i)());
}
prefix_ void senf::ppi::module::PriorityJoin::onThrottle()
{
if (std::find_if(inputs_.begin(), inputs_.end(),
- ! bind(&connector::ActiveInput::throttled, _1)) == inputs_.end())
+ ! bind(&connector::GenericActiveInput::throttled, _1)) == inputs_.end())
output.throttle();
}
// senf::ppi::module::PassiveJoin
template <class Source>
-prefix_ senf::ppi::connector::PassiveInput &
+prefix_ senf::ppi::connector::GenericPassiveInput &
senf::ppi::module::PassiveJoin::connect(Source & source)
{
- connector::PassiveInput & input (newInput());
+ connector::GenericPassiveInput & input (newInput());
ppi::connect(source,input);
return input;
}
// senf::ppi::module::PriorityJoin
template <class Source>
-prefix_ senf::ppi::connector::ActiveInput &
+prefix_ senf::ppi::connector::GenericActiveInput &
senf::ppi::module::PriorityJoin::connect(Source & source)
{
- connector::ActiveInput & input (newInput());
+ connector::GenericActiveInput & input (newInput());
ppi::connect(source,input);
return input;
}
#ifndef DOXYGEN
template <class Source>
-prefix_ senf::ppi::connector::PassiveInput & senf::ppi::connect(Source & source,
+prefix_ senf::ppi::connector::GenericPassiveInput & senf::ppi::connect(Source & source,
module::PassiveJoin & target)
{
return target.connect(source);
}
template <class Source>
-prefix_ senf::ppi::connector::ActiveInput & senf::ppi::connect(Source & source,
+prefix_ senf::ppi::connector::GenericActiveInput & senf::ppi::connect(Source & source,
module::PriorityJoin & target)
{
return target.connect(source);
#ifndef DOXYGEN
template <class Source>
- connector::PassiveInput & connect(Source & source, module::PassiveJoin & target);
+ connector::GenericPassiveInput & connect(Source & source, module::PassiveJoin & target);
template <class Source>
- connector::ActiveInput & connect(Source & source, module::PriorityJoin & target);
+ connector::GenericActiveInput & connect(Source & source, module::PriorityJoin & target);
#endif
/** \brief Join multiple packet streams with passive inputs
The PassiveJoin will combine any number of packet streams. You may connect any number of
- ActiveOutput's to the PassiveJoin instance. The combined stream is then provided on the
- ActiveOutput \a output.
+ GenericActiveOutput's to the PassiveJoin instance. The combined stream is then provided on the
+ GenericActiveOutput \a output.
Since PassiveJoin allows any number of incoming packet streams, the input connectors are
dynamically managed. A special senf::ppi::connect() overload is used to dynamically create
{
SENF_PPI_MODULE(PassiveJoin);
public:
- connector::ActiveOutput output;
+ connector::GenericActiveOutput output;
PassiveJoin();
private:
- connector::PassiveInput & newInput();
+ connector::GenericPassiveInput & newInput();
#ifndef DOXYGEN
// I didn't get template friend functions to work ...
public:
#endif
template <class Source>
- connector::PassiveInput & connect(Source & source);
+ connector::GenericPassiveInput & connect(Source & source);
private:
- void request(connector::PassiveInput & input);
+ void request(connector::GenericPassiveInput & input);
void onThrottle();
void onUnthrottle();
- typedef boost::ptr_vector<connector::PassiveInput> Inputs;
+ typedef boost::ptr_vector<connector::GenericPassiveInput > Inputs;
Inputs inputs_;
};
/** \brief Join multiple packet streams with active inputs
The PriorityJoin will combine any number of packet streams. You may connect any number of
- PassiveInput's to the PassiveJoin instance. The combined stream is then provided on the
- PassiveOutput \a output.
+ GenericPassiveInput's to the PassiveJoin instance. The combined stream is then provided on the
+ GenericPassiveOutput \a output.
When a packet request is received on Priorityjoin's \a output, The request will be serviced
from the first unthrottled input. The order, in which connectors are connected to the
{
SENF_PPI_MODULE(PriorityJoin);
public:
- connector::PassiveOutput output;
+ connector::GenericPassiveOutput output;
PriorityJoin();
private:
- connector::ActiveInput & newInput();
+ connector::GenericActiveInput & newInput();
#ifndef DOXYGEN
public:
#endif
template <class Source>
- connector::ActiveInput & connect(Source & source);
+ connector::GenericActiveInput & connect(Source & source);
private:
void request();
void onThrottle();
void onUnthrottle();
- typedef boost::ptr_vector<connector::ActiveInput> Inputs;
+ typedef boost::ptr_vector<connector::GenericActiveInput> Inputs;
Inputs inputs_;
};
senf::ppi::IntervalTimer timer_;
public:
- senf::ppi::connector::ActiveInput payload;
- senf::ppi::connector::ActiveInput stuffing;
- senf::ppi::connector::ActiveOutput output;
+ senf::ppi::connector::GenericActiveInput payload;
+ senf::ppi::connector::GenericActiveInput stuffing;
+ senf::ppi::connector::GenericActiveOutput output;
RateStuffer(unsigned packetsPerSecond)
: timer_(1000u, packetsPerSecond)
{
SENF_PPI_MODULE(CopyPacketGenerator);
public:
- senf::ppi::connector::PassiveOutput output;
+ senf::ppi::connector::GenericPassiveOutput output;
CopyPacketGenerator(Packet template)
: template_ (template)
The input and output attachment points of a module are called connectors. Each connector may be
active or passive. This gives us 4 types of connectors:
- \li senf::ppi::connector::ActiveInput
- \li senf::ppi::connector::ActiveOutput
- \li senf::ppi::connector::PassiveInput
- \li senf::ppi::connector::PassiveOutput
+ \li senf::ppi::connector::GenericActiveInput
+ \li senf::ppi::connector::GenericActiveOutput
+ \li senf::ppi::connector::GenericPassiveInput
+ \li senf::ppi::connector::GenericPassiveOutput
An \e active connector (input or output) is <em>activated by the module</em> to send data or to
poll for available packets. This means, the modules processing routine will call the connector
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;
+ senf::ppi::connector::PassiveInput<> input;
+ senf::ppi::connector::ActiveOutput<> output;
SomeModule(senf::FileHandle h)
: handle ( h ),
SENF_PPI_MODULE(TestModule);
public:
- connector::ActiveOutput output;
+ connector::ActiveOutput<> output;
ppi::DebugEvent event;
requested from the passive output, a packet is dequeued.
The PassiveQueue will automatically throttle in both directions. Throttling on the input
- connector is the standard throttling as implemented in connector::PassiveInput. Additional,
+ connector is the standard throttling as implemented in connector::GenericPassiveInput. Additional,
forward throttling notifications are sent out whenever the queue is empty.
\ingroup adapter_modules
{
SENF_PPI_MODULE(PassiveQueue);
public:
- connector::PassiveInput input;
- connector::PassiveOutput output;
+ connector::PassiveInput<> input;
+ connector::PassiveOutput<> output;
PassiveQueue();
queue. This call is just forwarded to the \a input
connector.
- \see connector::PassiveInput::qdisc() */
+ \see connector::GenericPassiveInput::qdisc() */
private:
void init();
///////////////////////////////////////////////////////////////////////////
// senf::ppi::ThresholdQueueing
-prefix_ void senf::ppi::ThresholdQueueing::update(connector::PassiveInput & input, Event event)
+prefix_ void senf::ppi::ThresholdQueueing::update(connector::GenericPassiveInput & input, Event event)
{
switch (event) {
case ENQUEUE:
enum Event { ENQUEUE, DEQUEUE }; ///< Possible queueing events
- virtual void update(connector::PassiveInput & input, Event event) = 0;
+ virtual void update(connector::GenericPassiveInput & input, Event event) = 0;
///< Calculate new queueing state
/**< Whenever the queue is manipulated, this member is
called to calculate the new throttling state. The
public:
ThresholdQueueing(unsigned high, unsigned low);
- virtual void update(connector::PassiveInput & input, Event event);
+ virtual void update(connector::GenericPassiveInput & input, Event event);
private:
unsigned high_;
{
SENF_PPI_MODULE(QueueTester);
public:
- connector::PassiveInput input;
- connector::ActiveOutput output;
+ connector::PassiveInput<> input;
+ connector::ActiveOutput<> output;
QueueTester() {
route(input, output);
{
//timer = ppi::IntervalTimer(interval);
}
-*/
\ No newline at end of file
+*/
SENF_PPI_MODULE(RateFilter);
public:
- connector::ActiveInput input;
- connector::ActiveOutput output;
+ connector::ActiveInput<> input;
+ connector::ActiveOutput<> output;
RateFilter(senf::ClockService::clock_type interval);
// void changeInterval(senf::ClockService::clock_type interval); not yet implemented!
SENF_PPI_MODULE(RouteTester);
public:
- connector::ActiveInput activeIn;
- connector::PassiveInput passiveIn;
+ connector::ActiveInput<> activeIn;
+ connector::PassiveInput<> passiveIn;
- connector::ActiveOutput activeOut;
- connector::PassiveOutput passiveOut;
+ connector::ActiveOutput<> activeOut;
+ connector::PassiveOutput<> passiveOut;
ppi::DebugEvent event;
#ifndef DOXYGEN
-prefix_ void senf::ppi::connect(connector::ActiveOutput & source,
- connector::PassiveInput & target)
+prefix_ void senf::ppi::connect(connector::GenericActiveOutput & source,
+ connector::GenericPassiveInput & target)
{
source.connect(target);
}
-prefix_ void senf::ppi::connect(connector::PassiveOutput & source,
- connector::ActiveInput & target)
+prefix_ void senf::ppi::connect(connector::GenericPassiveOutput & source,
+ connector::GenericActiveInput & target)
{
source.connect(target);
}
\see \ref ppi_connections
*/
- void connect(connector::ActiveOutput & source, connector::PassiveInput & target);
+ void connect(connector::GenericActiveOutput & source, connector::GenericPassiveInput & target);
/** \brief Connect modules
\see connect() */
- void connect(connector::PassiveOutput & source, connector::ActiveInput & target);
+ void connect(connector::GenericPassiveOutput & source, connector::GenericActiveInput & target);
#ifndef DOXYGEN
public:
typedef typename Writer::Handle Handle; ///< Handle type requested by writer
- connector::ActiveInput input; ///< Input connector from which data is received
+ connector::ActiveInput<> input; ///< Input connector from which data is received
ActiveSocketSink(Handle handle); ///< Create new writer for the given handle
/**< Data will be written to \a handle using \a Writer.
public:
typedef typename Writer::Handle Handle; ///< Handle type requested by writer
- connector::PassiveInput input; ///< Input connector from which data is received
+ connector::PassiveInput<> input; ///< Input connector from which data is received
PassiveSocketSink(Handle handle); ///< Create new writer for the given handle
/**< Data will be written to \a handle using \a Writer.
public:
typedef typename Reader::Handle Handle; ///< Handle type requested by the reader
- connector::ActiveOutput output; ///< Output connector to which the data received is written
+ connector::ActiveOutput<> output; ///< Output connector to which the data received is written
ActiveSocketSource(Handle handle); ///< Create new reader for the given handle
/**< Data will be read from \a handle and be parsed by \a
SENF_PPI_MODULE(ThrottleBarrier);
public:
- connector::PassiveInput input;
- connector::ActiveOutput output;
+ connector::PassiveInput<> input;
+ connector::ActiveOutput<> output;
ThrottleBarrier();
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
+
+ class Packet;
+
namespace ppi {
class EventDescriptor;
class PassiveConnector;
class InputConnector;
class OutputConnector;
- class ActiveInput;
- class ActiveOutput;
- class PassiveInput;
- class PassiveOutput;
+ class GenericActiveInput;
+ class GenericActiveOutput;
+ class GenericPassiveInput;
+ class GenericPassiveOutput;
+ template <class PacketType=Packet> class PassiveInput;
+ template <class PacketType=Packet> class PassiveOutput;
+ template <class PacketType=Packet> class ActiveInput;
+ template <class PacketType=Packet> class ActiveOutput;
+
+#ifndef DOXYGEN
+
+ namespace detail {
+ template <class Self, class PacketType> class TypedInputMixin;
+ template <class Self, class PacketType> class TypedOutputMixin;
+ }
+
+#endif
+
}
}}