Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Directories
  • File List
  • File Members

Connectors.hh

Go to the documentation of this file.
00001 // $Id: Connectors.hh 1742 2010-11-04 14:51:56Z g0dil $
00002 //
00003 // Copyright (C) 2007
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #ifndef HH_SENF_PPI_Connectors_
00027 #define HH_SENF_PPI_Connectors_ 1
00028 
00029 // Custom includes
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 //#include "Connectors.mpp"
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         // Called by the routing to change the throttling state from forwarding routes
00262         void notifyThrottle();          
00263         void notifyUnthrottle();        
00264 
00265         // Internal members to emit throttling notifications to the connected peer
00266         void emitThrottle();
00267         void emitUnthrottle();
00268 
00269         // Called after unthrottling the connector
00270         virtual void v_unthrottleEvent();
00271 
00272         // called by ForwardingRoute to register a new route
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         // called by the peer() to forward throttling notifications
00347         void notifyThrottle();
00348         void notifyUnthrottle();
00349 
00350         // called by ForwardingRoute to register a new route
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 // Local Variables:
00709 // mode: c++
00710 // fill-column: 100
00711 // c-file-style: "senf"
00712 // indent-tabs-mode: nil
00713 // ispell-local-dictionary: "american"
00714 // compile-command: "scons -u test"
00715 // comment-column: 40
00716 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research