Socket: Ignore ECONNREFUSED on write to datagram socket
[senf.git] / PPI / Joins.hh
1 // $Id$
2 //
3 // Copyright (C) 2007 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Joins public header */
25
26 #ifndef HH_Joins_
27 #define HH_Joins_ 1
28
29 // Custom includes
30 #include <boost/ptr_container/ptr_vector.hpp>
31 #include "predecl.hh"
32 #include "Connectors.hh"
33 #include "Module.hh"
34
35 //#include "Joins.mpp"
36 ///////////////////////////////hh.p////////////////////////////////////////
37
38 namespace senf {
39 namespace ppi {
40
41 #ifndef DOXYGEN
42
43     template <class Source>
44     connector::PassiveInput & connect(Source & source, module::PassiveJoin & target);
45     
46     template <class Source>
47     connector::ActiveInput & connect(Source & source, module::PriorityJoin & target);
48
49 #endif
50
51 namespace module {
52
53     /** \brief Join multiple packet streams with passive inputs
54
55         The PassiveJoin will combine any number of packet streams. You may connect any number of
56         ActiveOutput's  to the PassiveJoin instance. The combined stream is then provided on the
57         ActiveOutput \a output.
58
59         Since PassiveJoin allows any number of incoming packet streams, the input connectors are
60         dynamically managed. A special senf::ppi::connect() overload is used to dynamically create
61         the needed input connectors. This hides this extra functionality from the user.
62         \code
63         senf::ppi::module::PassiveJoin join;
64
65         ppi::connect(module1,join);             // Connect first module to join's input
66         ppi::connect(module2.some_output,join); // Connect another module to join's input
67         ppi::connect(join,module3);             // Forward combined stream to module3
68         \endcode
69
70         \ingroup routing_modules
71      */
72     class PassiveJoin
73         : public Module
74     {
75         SENF_PPI_MODULE(PassiveJoin);
76     public:
77         connector::ActiveOutput output;
78
79         PassiveJoin();
80
81     private:
82         connector::PassiveInput & newInput();
83
84 #ifndef DOXYGEN
85         // I didn't get template friend functions to work ...
86     public:
87 #endif
88         template <class Source>
89         connector::PassiveInput & connect(Source & source);
90
91     private:
92         void request(connector::PassiveInput & input);
93         void onThrottle();
94         void onUnthrottle();
95
96         typedef boost::ptr_vector<connector::PassiveInput> Inputs;
97         Inputs inputs_;
98     };
99
100     /** \brief Join multiple packet streams with active inputs
101
102         The PriorityJoin will combine any number of packet streams. You may connect any number of
103         PassiveInput's  to the PassiveJoin instance. The combined stream is then provided on the
104         PassiveOutput \a output.
105
106         When a packet request is received on Priorityjoin's \a output, The request will be serviced
107         from the first unthrottled input. The order, in which connectors are connected to the
108         PriorityJoin's input is important: The earlier connected peer has the higher priority and
109         will be serviced first.
110
111         Since PriorityJoin allows any number of incoming packet streams, the input connectors are
112         dynamically managed. A special senf::ppi::connect() overload is used to dynamically create
113         the needed input connectors. This hides this extra functionality from the user.
114         \code
115         senf::ppi::module::PriorityJoin join;
116
117         ppi::connect(module1,join);             // Connect first module to join's input
118         ppi::connect(module2.some_output,join); // Connect another module to join's input
119         ppi::connect(join,module3);             // Forward combined stream to module3
120         \endcode
121         Here, \a module1 has higher priority than \a module2 which will only be queried if \a
122         module1 is throttled.
123         
124         \ingroup routing_modules
125      */
126     class PriorityJoin
127         : public Module
128     {
129         SENF_PPI_MODULE(PriorityJoin);
130     public:
131         connector::PassiveOutput output;
132
133         PriorityJoin();
134
135     private:
136         connector::ActiveInput & newInput();
137
138 #ifndef DOXYGEN
139     public:
140 #endif
141         template <class Source>
142         connector::ActiveInput & connect(Source & source);
143
144     private:
145         void request();
146         void onThrottle();
147         void onUnthrottle();
148
149         typedef boost::ptr_vector<connector::ActiveInput> Inputs;
150         Inputs inputs_;
151     };
152
153 }}}
154
155 ///////////////////////////////hh.e////////////////////////////////////////
156 #include "Joins.cci"
157 //#include "Joins.ct"
158 #include "Joins.cti"
159 #endif
160
161 \f
162 // Local Variables:
163 // mode: c++
164 // fill-column: 100
165 // comment-column: 40
166 // c-file-style: "senf"
167 // indent-tabs-mode: nil
168 // ispell-local-dictionary: "american"
169 // compile-command: "scons -u test"
170 // End: