00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #ifndef HH_SENF_PPI_Connectors_
00027 #define HH_SENF_PPI_Connectors_ 1
00028
00029
00030 #include <deque>
00031 #include <boost/utility.hpp>
00032 #include <boost/scoped_ptr.hpp>
00033 #include <senf/Utils/safe_bool.hh>
00034 #include <senf/Utils/Exception.hh>
00035 #include <senf/Packets/Packets.hh>
00036 #include "predecl.hh"
00037 #include "detail/Callback.hh"
00038 #include "Queueing.hh"
00039 #include "ModuleManager.hh"
00040
00041
00042
00043
00044 namespace senf {
00045 namespace ppi {
00046 namespace connector {
00047
00152 struct IncompatibleConnectorsException : public senf::Exception
00153 { IncompatibleConnectorsException() : senf::Exception("Incompatible connectors") {} };
00154
00161 class Connector
00162 : ModuleManager::Initializable, boost::noncopyable
00163 {
00164 SENF_LOG_CLASS_AREA();
00165 SENF_LOG_DEFAULT_LEVEL(senf::log::NOTICE);
00166 public:
00167 Connector & peer() const;
00168 module::Module & module() const;
00169
00170 bool connected() const;
00171
00172 void disconnect();
00173
00174 enum TraceState { NO_TRACING, TRACE_IDS, TRACE_CONTENTS };
00175
00176 static void tracing(TraceState state);
00177 static TraceState tracing();
00178
00179 protected:
00180 Connector();
00181 virtual ~Connector();
00182
00183 void connect(Connector & target);
00184
00185 void trace(Packet const & p, char const * label);
00186 void throttleTrace(char const * label, char const * type);
00187
00188 void unregisterConnector();
00189
00190 virtual void v_disconnected();
00191 virtual void v_connected();
00192
00193 private:
00194 virtual std::type_info const & packetTypeID();
00195
00196 void setModule(module::Module & module);
00197
00198 Connector * peer_;
00199 module::Module * module_;
00200
00201 static TraceState traceState_;
00202
00203 friend class module::Module;
00204 };
00205
00222 class PassiveConnector
00223 : public virtual Connector
00224 {
00225 public:
00226 ~PassiveConnector();
00227
00228 template <class Handler>
00229 void onRequest(Handler handler);
00230
00242 bool throttled() const;
00243 bool nativeThrottled() const;
00244
00245 void throttle();
00246 void unthrottle();
00247
00248 ActiveConnector & peer() const;
00249
00250 protected:
00251 PassiveConnector();
00252
00253 void emit();
00254
00255 virtual void v_disconnected();
00256 virtual void v_connected();
00257
00258 private:
00259 virtual void v_init();
00260
00261
00262 void notifyThrottle();
00263 void notifyUnthrottle();
00264
00265
00266 void emitThrottle();
00267 void emitUnthrottle();
00268
00269
00270 virtual void v_unthrottleEvent();
00271
00272
00273 void registerRoute(ForwardingRoute & route);
00274 void unregisterRoute(ForwardingRoute & route);
00275
00276 ActiveConnector * peer_;
00277
00278 typedef ppi::detail::Callback<>::type Callback;
00279 Callback callback_;
00280
00281 bool remoteThrottled_;
00282 bool nativeThrottled_;
00283
00284 typedef std::vector<ForwardingRoute*> Routes;
00285 Routes routes_;
00286
00287 friend class senf::ppi::ForwardingRoute;
00288 };
00289
00300 class ActiveConnector
00301 : public virtual Connector
00302 {
00303 typedef ppi::detail::Callback<>::type Callback;
00304 public:
00305 ~ActiveConnector();
00306
00307 template <class Handler>
00308 void onThrottle(Handler handler);
00309
00318 void onThrottle();
00319
00320 template <class Handler>
00321 void onUnthrottle(Handler handler);
00322
00331 void onUnthrottle();
00332
00333 bool throttled() const;
00334
00335 PassiveConnector & peer() const;
00336
00337 protected:
00338 ActiveConnector();
00339
00340 virtual void v_disconnected();
00341 virtual void v_connected();
00342
00343 private:
00344 virtual void v_init();
00345
00346
00347 void notifyThrottle();
00348 void notifyUnthrottle();
00349
00350
00351 void registerRoute(ForwardingRoute & route);
00352 void unregisterRoute(ForwardingRoute & route);
00353
00354 PassiveConnector * peer_;
00355
00356 Callback throttleCallback_;
00357 Callback unthrottleCallback_;
00358
00359 typedef std::vector<ForwardingRoute*> NotifyRoutes;
00360 NotifyRoutes notifyRoutes_;
00361
00362 bool throttled_;
00363
00364 friend class senf::ppi::ForwardingRoute;
00365 friend class PassiveConnector;
00366 };
00367
00388 class InputConnector
00389 : public virtual Connector
00390 {
00391 typedef std::deque<Packet> Queue;
00392 public:
00393 typedef Queue::const_iterator queue_iterator;
00394 typedef Queue::size_type size_type;
00395
00396
00397 Packet operator()();
00398
00406 Packet read();
00407
00408 OutputConnector & peer() const;
00409
00410 queue_iterator begin() const;
00411 queue_iterator end() const;
00412 Packet peek() const;
00413
00414 size_type queueSize() const;
00415 bool empty() const;
00416
00417 protected:
00418 InputConnector();
00419
00420 virtual void v_disconnected();
00421 virtual void v_connected();
00422
00423 private:
00424 void enqueue(Packet const & p);
00425
00426 virtual void v_requestEvent();
00427 virtual void v_enqueueEvent();
00428 virtual void v_dequeueEvent();
00429
00430 OutputConnector * peer_;
00431 Queue queue_;
00432
00433 friend class OutputConnector;
00434 };
00435
00442 class OutputConnector
00443 : public virtual Connector
00444 {
00445 public:
00446 void operator()(Packet const & p);
00447
00448 void write(Packet const & p);
00449
00450 InputConnector & peer() const;
00451
00452 protected:
00453 OutputConnector();
00454
00455 virtual void v_disconnected();
00456 virtual void v_connected();
00457
00458 private:
00459 InputConnector * peer_;
00460 };
00461
00471 class GenericPassiveInput
00472 : public PassiveConnector, public InputConnector,
00473 public safe_bool<GenericPassiveInput>
00474 {
00475 public:
00476 GenericActiveOutput & peer() const;
00477
00478 bool boolean_test() const;
00479
00480 template <class QDisc>
00481 void qdisc(QDisc const & disc);
00482
00486 void qdisc(QueueingDiscipline::None_t);
00488
00489 protected:
00490 GenericPassiveInput();
00491
00492 virtual void v_disconnected();
00493 virtual void v_connected();
00494
00495 private:
00496 void v_enqueueEvent();
00497 void v_dequeueEvent();
00498 void v_unthrottleEvent();
00499
00500 GenericActiveOutput * peer_;
00501 boost::scoped_ptr<QueueingDiscipline> qdisc_;
00502 };
00503
00506 class GenericPassiveOutput
00507 : public PassiveConnector, public OutputConnector,
00508 public safe_bool<GenericPassiveOutput>
00509 {
00510 public:
00511 GenericActiveInput & peer() const;
00512
00513 bool boolean_test() const;
00514
00515 void connect(GenericActiveInput & target);
00516
00517 friend class GenericActiveInput;
00518
00519 protected:
00520 GenericPassiveOutput();
00521
00522 virtual void v_disconnected();
00523 virtual void v_connected();
00524
00525 private:
00526 GenericActiveInput * peer_;
00527 };
00528
00531 class GenericActiveInput
00532 : public ActiveConnector, public InputConnector,
00533 public safe_bool<GenericActiveInput>
00534 {
00535 public:
00536 GenericPassiveOutput & peer() const;
00537
00538 bool boolean_test() const;
00539
00540 void request();
00541
00542 protected:
00543 GenericActiveInput();
00544
00545 virtual void v_disconnected();
00546 virtual void v_connected();
00547
00548 private:
00549 void v_requestEvent();
00550
00551 GenericPassiveOutput * peer_;
00552 };
00553
00556 class GenericActiveOutput
00557 : public ActiveConnector, public OutputConnector,
00558 public safe_bool<GenericActiveOutput>
00559 {
00560 public:
00561 GenericPassiveInput & peer() const;
00562
00563 bool boolean_test() const;
00564
00565 void connect(GenericPassiveInput & target);
00566
00567 protected:
00568 GenericActiveOutput();
00569
00570 virtual void v_disconnected();
00571 virtual void v_connected();
00572
00573 private:
00574 GenericPassiveInput * peer_;
00575 };
00576
00577
00578 #ifndef DOXYGEN
00579
00580 # define TypedConnector_Input read
00581 # define TypedConnector_Output write
00582 # define TypedConnector(pType, dir) \
00583 template <class PacketType> \
00584 class pType ## dir \
00585 : public Generic ## pType ## dir, \
00586 private detail::Typed ## dir ## Mixin<pType ## dir <PacketType>, PacketType> \
00587 { \
00588 typedef detail::Typed ## dir ## Mixin<pType ## dir <PacketType>, PacketType> mixin; \
00589 public: \
00590 using mixin::operator(); \
00591 using mixin::TypedConnector_ ## dir ; \
00592 private: \
00593 virtual std::type_info const & packetTypeID() \
00594 { return typeid(typename PacketType::type); } \
00595 friend class detail::Typed ## dir ## Mixin<pType ## dir <PacketType>, PacketType>; \
00596 }; \
00597 template <> \
00598 class pType ## dir <Packet> : public Generic ## pType ## dir \
00599 {}
00600
00601 TypedConnector( Passive, Input );
00602 TypedConnector( Passive, Output );
00603 TypedConnector( Active, Input );
00604 TypedConnector( Active, Output );
00605
00606 # undef TypedConnector
00607 # undef TypedConnector_Input
00608 # undef TypedConnector_Output
00609
00610 #else
00611
00624 template <class PacketType=Packet>
00625 class ActiveInput : public GenericActiveInput
00626 {
00627 public:
00628 PacketType operator()();
00629
00632 PacketType read();
00633 };
00634
00647 template <class PacketType=Packet>
00648 class PassiveInput : public GenericPassiveInput
00649 {
00650 public:
00651 PacketType operator()();
00652
00655 PacketType read();
00656 };
00657
00669 template <class PacketType=Packet>
00670 class ActiveOutput : public GenericActiveOutput
00671 {
00672 public:
00673 void operator()(PacketType packet);
00674 void write(PacketType packet);
00675 };
00676
00689 template <class PacketType=Packet>
00690 class PassiveOutput : public GenericPassiveOutput
00691 {
00692 public:
00693 void operator()(PacketType packet);
00694 void write(PacketType packet);
00695 };
00696
00697 #endif
00698
00699 }}}
00700
00701
00702 #include "Connectors.cci"
00703 #include "Connectors.ct"
00704 #include "Connectors.cti"
00705 #endif
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716