////////////////////////////////////////
// private members
+prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle()
+{
+ if (throttled() && !nativeThrottled_) {
+ Routes::const_iterator i (routes_.begin());
+ Routes::const_iterator const i_end (routes_.end());
+ for (; i != i_end; ++i)
+ if ((*i)->throttled())
+ break;
+ if (i == i_end) {
+ remoteThrottled_ = false;
+ emitUnthrottle();
+ }
+ }
+ else
+ remoteThrottled_ = false;
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::ActiveConnector
remoteThrottled_ = true;
}
-prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle()
-{
- if (throttled() && !nativeThrottled_) {
- remoteThrottled_ = false;
- emitUnthrottle();
- }
- else
- remoteThrottled_ = false;
-}
-
prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle()
{
peer().notifyThrottle();
prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent()
{}
+prefix_ void senf::ppi::connector::PassiveConnector::registerRoute(ForwardingRoute & route)
+{
+ routes_.push_back(&route);
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::ppi::connector::ActiveConnector
unthrottleCallback_ = Callback();
}
+prefix_ bool senf::ppi::connector::ActiveConnector::throttled()
+ const
+{
+ return peer().throttled();
+}
+
////////////////////////////////////////
// protected members
// Called after unthrottling the connector
virtual void v_unthrottleEvent();
+ // called by ForwardingRoute to register a new route
+ void registerRoute(ForwardingRoute & route);
+
typedef detail::Callback<>::type Callback;
Callback callback_;
bool remoteThrottled_;
bool nativeThrottled_;
+ typedef std::vector<ForwardingRoute*> Routes;
+ Routes routes_;
+
friend class senf::ppi::ForwardingRoute;
};
notifications. */
void onUnthrottle();
+ bool throttled() const;
+
PassiveConnector & peer() const;
protected:
output(packet);
}
+prefix_ bool senf::ppi::module::debug::ActivePacketSource::boolean_test()
+ const
+{
+ return output;
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::ppi::module::debug::PassivePacketSource
return input();
}
+prefix_ bool senf::ppi::module::debug::ActivePacketSink::boolean_test()
+ const
+{
+ return input;
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::ppi::module::debug::PassivePacketSink
// Custom includes
#include <deque>
+#include "Utils/SafeBool.hh"
#include "Packets/Packets.hh"
#include "Module.hh"
namespace debug {
class ActivePacketSource
- : public Module
+ : public Module,
+ public SafeBool<ActivePacketSource>
{
public:
connector::ActiveOutput output;
ActivePacketSource();
void submit(Packet packet);
+
+ bool boolean_test() const;
};
class PassivePacketSource
};
class ActivePacketSink
- : public Module
+ : public Module,
+ public SafeBool<ActivePacketSink>
{
public:
connector::ActiveInput input;
ActivePacketSink();
Packet request();
+
+ bool boolean_test() const;
};
class PassivePacketSink
--- /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 Events non-inline non-template implementation */
+
+#include "Events.hh"
+#include "Events.ih"
+
+// Custom includes
+#include "Route.hh"
+
+//#include "Events.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::ppi::EventDescriptor
+
+prefix_ void senf::ppi::EventDescriptor::notifyUnthrottle()
+{
+ Routes::const_iterator i (routes_.begin());
+ Routes::const_iterator const i_end (routes_.end());
+ for (; i != i_end; ++i)
+ if ((*i)->throttled())
+ break;
+ if (i == i_end)
+ enabled(true);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "Events.mpp"
+
+\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:
enabled(false);
}
-prefix_ void senf::ppi::EventDescriptor::notifyUnthrottle()
+prefix_ void senf::ppi::EventDescriptor::registerRoute(ForwardingRoute & route)
{
- enabled(true);
+ routes_.push_back(&route);
}
-
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
#define HH_Events_ 1
// Custom includes
+#include <vector>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include "predecl.hh"
void notifyThrottle();
void notifyUnthrottle();
+ void registerRoute(ForwardingRoute & route);
+
bool enabled_;
+ typedef std::vector<ForwardingRoute*> Routes;
+ Routes routes_;
+
friend class ForwardingRoute;
};
// senf::ppi::ForwardingRoute
prefix_ bool senf::ppi::ForwardingRoute::autoThrottling()
+ const
{
return autoThrottling_;
}
autoThrottling_ = state;
}
+prefix_ bool senf::ppi::ForwardingRoute::throttled()
+ const
+{
+ return v_throttled();
+}
+
////////////////////////////////////////
// protected members
: RouteBase(module), autoThrottling_(true)
{}
-prefix_ void senf::ppi::ForwardingRoute::registerRoute(connector::ActiveConnector & connector)
-{
- connector.registerRoute(*this);
-}
-
////////////////////////////////////////
// private members
}
}
+template <class Source, class Target>
+prefix_ bool senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::v_throttled()
+ const
+{
+ return this->autoThrottling() && (
+ throttled(this->source(),boost::mpl::bool_<RoutingTraits<Source>::notifySource>()) ||
+ throttled(this->target(),boost::mpl::bool_<RoutingTraits<Target>::notifySource>()) );
+}
+
///////////////////////////////ct.e////////////////////////////////////////
#undef prefix_
// protected members
template <class T>
+prefix_ void senf::ppi::ForwardingRoute::registerRoute(T & ob)
+{
+ ob.registerRoute(*this);
+}
+
+template <class T>
prefix_ void senf::ppi::ForwardingRoute::notifyThrottle(T & ob)
{
ob.notifyThrottle();
template <class Source, class Target, class Base>
prefix_ Source & senf::ppi::detail::BaseRouteImplementation<Source,Target,Base>::source()
+ const
{
return *source_;
}
template <class Source, class Target, class Base>
prefix_ Target & senf::ppi::detail::BaseRouteImplementation<Source,Target,Base>::target()
+ const
{
return *target_;
}
ForwardingRouteImplementation(module::Module & module, Source & source, Target & target)
: Base(module,source,target)
{
- registerRoute(source, boost::mpl::bool_<RoutingTraits<Source>::notifySource>());
- registerRoute(target, boost::mpl::bool_<RoutingTraits<Target>::notifySource>());
+ registerRoute(source);
+ registerRoute(target);
}
////////////////////////////////////////
template <class Source, class Target>
template <class T>
prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
-registerRoute(T & ob, boost::mpl::bool_<true> const &)
+notifyThrottle(T & ob, boost::mpl::bool_<true> const &)
{
- ForwardingRoute::registerRoute(ob);
+ ForwardingRoute::notifyThrottle(ob);
}
template <class Source, class Target>
template <class T>
prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
-registerRoute(T & ob, boost::mpl::bool_<false> const &)
+notifyThrottle(T & ob, boost::mpl::bool_<false> const &)
{}
template <class Source, class Target>
template <class T>
prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
-notifyThrottle(T & ob, boost::mpl::bool_<true> const &)
+notifyUnthrottle(T & ob, boost::mpl::bool_<true> const &)
{
- ForwardingRoute::notifyThrottle(ob);
+ ForwardingRoute::notifyUnthrottle(ob);
}
template <class Source, class Target>
template <class T>
prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
-notifyThrottle(T & ob, boost::mpl::bool_<false> const &)
+notifyUnthrottle(T & ob, boost::mpl::bool_<false> const &)
{}
template <class Source, class Target>
template <class T>
-prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
-notifyUnthrottle(T & ob, boost::mpl::bool_<true> const &)
+prefix_ bool senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
+throttled(T & ob, boost::mpl::bool_<true> const &)
+ const
{
- ForwardingRoute::notifyUnthrottle(ob);
+ return ob.throttled();
}
template <class Source, class Target>
template <class T>
-prefix_ void senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
-notifyUnthrottle(T & ob, boost::mpl::bool_<false> const &)
-{}
+prefix_ bool senf::ppi::detail::ForwardingRouteImplementation<Source,Target>::
+throttled(T & ob, boost::mpl::bool_<false> const &)
+ const
+{
+ return false;
+}
///////////////////////////////////////////////////////////////////////////
// senf::ppi::detail::RouteImplementation2<Source,Target>
: public RouteBase
{
public:
- bool autoThrottling();
+ bool autoThrottling() const;
void autoThrottling(bool state); ///< Change automatic throttle notification forwarding
/**< By default, throttle notifications are automatically
forwarded from active to passive connectors. This may
comes in. Respective for unthrottle notifications.
\param[in] state New throttle forwarding state */
+
+ bool throttled() const;
protected:
ForwardingRoute(module::Module & module);
// Called to register this route with the connectors forwarding information base
- void registerRoute(connector::ActiveConnector & connector);
+ template <class T> void registerRoute(T & ob);
template <class T> void notifyThrottle(T & ob);
template <class T> void notifyUnthrottle(T & ob);
// Implemented in the derived classes to forward throttling notifications
virtual void v_notifyThrottle() = 0;
virtual void v_notifyUnthrottle() = 0;
+ virtual bool v_throttled() const = 0;
bool autoThrottling_;
typedef Source source_type;
typedef Target target_type;
- Source & source();
- Target & target();
+ Source & source() const;
+ Target & target() const;
protected:
BaseRouteImplementation(module::Module & module, Source & source, Target & target);
ForwardingRouteImplementation(module::Module & module, Source & source, Target & target);
private:
- // register the Route in the notifySource only if the second argument is a 'true' type
- template <class T> void registerRoute(T & ob, boost::mpl::bool_<true> const &);
- template <class T> void registerRoute(T & ob, boost::mpl::bool_<false> const &);
-
// send a throttle/unthrottle notification only if the second argument is a 'true' type
template <class T> void notifyThrottle(T & ob, boost::mpl::bool_<true> const &);
template <class T> void notifyThrottle(T & ob, boost::mpl::bool_<false> const &);
template <class T> void notifyUnthrottle(T & ob, boost::mpl::bool_<true> const &);
template <class T> void notifyUnthrottle(T & ob, boost::mpl::bool_<false> const &);
+ template <class T> bool throttled(T & ob, boost::mpl::bool_<true> const &) const;
+ template <class T> bool throttled(T & ob, boost::mpl::bool_<false> const &) const;
+
virtual void v_notifyThrottle();
virtual void v_notifyUnthrottle();
+ virtual bool v_throttled() const;
};
// This helper class finds the base-class suitable for a specific route. Routes are classified
BOOST_CHECK( ! tester.activeOut );
BOOST_CHECK_EQUAL( tester.throttles, 1 );
BOOST_CHECK( tester.passiveIn.throttled() );
- BOOST_CHECK( ! activeSource.output );
+ BOOST_CHECK( ! activeSource );
BOOST_CHECK( ! tester.event.enabled() );
passiveSink.input.unthrottle();
- BOOST_CHECK( activeSource.output );
+ BOOST_CHECK( activeSource );
BOOST_CHECK( tester.event.enabled() );
-
// Now throttle the passive source by exhausting the queue
BOOST_CHECK( p1 == activeSink.request() );
BOOST_CHECK( ! tester.activeIn );
BOOST_CHECK_EQUAL( tester.throttles, 1 );
BOOST_CHECK( tester.passiveOut.throttled() );
- BOOST_CHECK( ! activeSink.input );
+ BOOST_CHECK( ! activeSink );
BOOST_CHECK( ! tester.event.enabled() );
passiveSource.submit(p1);
- BOOST_CHECK( activeSink.input );
+ BOOST_CHECK( activeSink );
+ BOOST_CHECK( tester.event.enabled() );
+
+ // Check correct combination of multiple throttling events
+
+ activeSink.request();
+ BOOST_CHECK( ! tester.event.enabled() );
+ passiveSink.input.throttle();
+ BOOST_CHECK( ! tester.event.enabled() );
+ passiveSource.submit(p1);
+ BOOST_CHECK( ! tester.event.enabled() );
+ passiveSink.input.unthrottle();
BOOST_CHECK( tester.event.enabled() );
tester.rt->autoThrottling(false);
BOOST_CHECK( p1 == activeSink.request() );
BOOST_CHECK( passiveSource.output.throttled() );
- BOOST_CHECK( activeSink.input );
+ BOOST_CHECK( activeSink );
}
///////////////////////////////cc.e////////////////////////////////////////