switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / PPI / QueueingSocketSink.ct
1 // $Id$
2 //
3 // Copyright (C) 2010
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Thorsten Horstmann <tho@berlios.de>
27
28 /** \file
29     \brief QueueingSocketSink non-inline template implementation  */
30
31 //#include "QueueingSocketSink.ih"
32
33 // Custom includes
34 #include <senf/Utils/Console/ParsedCommand.hh>
35
36 #define prefix_
37 //-/////////////////////////////////////////////////////////////////////////////////////////////////
38
39 //-/////////////////////////////////////////////////////////////////////////////////////////////////
40 // senf::ppi::QueueingAlgorithmRegistry
41
42 template <class QAlgorithm>
43 prefix_ void senf::ppi::QueueingAlgorithmRegistry::registerQAlgorithm(std::string key)
44 {
45     if (qAlgoMap_.find( key) == qAlgoMap_.end() )
46         qAlgoMap_.insert(key, new detail::QueueingAlgorithmRegistry_Entry<QAlgorithm>() );
47     else
48         throw Exception("Duplicated QAlgorithm Registration ") << key;
49 }
50
51 //-/////////////////////////////////////////////////////////////////////////////////////////////////
52 // senf::ppi::detail::QueueingAlgorithmRegistry_Entry<QAlgorithm>
53
54 template <class QAlgorithm>
55 prefix_ senf::ppi::QueueingAlgorithm::ptr senf::ppi::detail::QueueingAlgorithmRegistry_Entry<QAlgorithm>::create()
56     const
57 {
58     return QAlgorithm::create();
59 }
60
61 //-/////////////////////////////////////////////////////////////////////////////////////////////////
62 // senf::ppi::module::PassiveQueueingSocketSink<Writer>
63
64 template <class Writer>
65 prefix_ senf::ppi::module::PassiveQueueingSocketSink<Writer>::PassiveQueueingSocketSink(Handle const & handle, QueueingAlgorithm::ptr qAlgorithm)
66     : dir( this),
67       handle_( handle), writer_( ),
68       qAlgo_( qAlgorithm),
69       event_( handle_, IOEvent::Write)
70 {
71     namespace fty = console::factory;
72     dir.add( "active", qAlgo_->consoleDir());
73     dir.add( "set", fty::Command(
74             &PassiveQueueingSocketSink<Writer>::setQAlgorithm, this) );
75     dir.add( "list", fty::Command(
76             &QueueingAlgorithmRegistry::dump, &QueueingAlgorithmRegistry::instance()));
77     registerEvent( event_, &PassiveQueueingSocketSink::writable );
78     event_.enabled( false);
79     noroute(input);
80     input.onRequest( &PassiveQueueingSocketSink::write);
81     input.qdisc( QueueingDiscipline::NONE);
82     checkThrottle();
83 }
84
85 template <class Writer>
86 prefix_ void senf::ppi::module::PassiveQueueingSocketSink<Writer>::handle(Handle const & handle)
87 {
88     handle_ = handle;
89     event_.set( handle_, IOEvent::Write);
90     qAlgo_->clear();
91     checkThrottle();
92 }
93
94 template <class Writer>
95 prefix_ void senf::ppi::module::PassiveQueueingSocketSink<Writer>::write()
96 {
97     PacketType p ( input());
98     if (qAlgo_->size() > 0) {
99         qAlgo_->enqueue( p);
100         return;
101     }
102     if (! writer_( handle_, p)) {
103         if (qAlgo_->enqueue( p) && !event_.enabled()) {
104           event_.enabled( true);
105         }
106     }
107 }
108
109 template <class Writer>
110 prefix_ void senf::ppi::module::PassiveQueueingSocketSink<Writer>::writable()
111 {
112     PacketType p (qAlgo_->dequeue());
113     if (p)
114         writer_( handle_, p);
115     if (qAlgo_->size() == 0) {
116         event_.enabled( false);
117     }
118 }
119
120 template <class Writer>
121 prefix_ void senf::ppi::module::PassiveQueueingSocketSink<Writer>::checkThrottle()
122 {
123     if (handle_.valid())
124         input.unthrottle();
125     else
126         input.throttle();
127 }
128
129 template <class Writer>
130 prefix_ void senf::ppi::module::PassiveQueueingSocketSink<Writer>::qAlgorithm(QueueingAlgorithm::ptr qAlgorithm)
131 {
132 //    dir.remove( "active");
133     qAlgo_.reset( qAlgorithm);
134     dir.add( "active", qAlgo_->consoleDir());
135     if (event_.enabled())
136         event_.enabled( false);
137 }
138
139 template <class Writer>
140 prefix_ void senf::ppi::module::PassiveQueueingSocketSink<Writer>::setQAlgorithm(std::string const & key)
141 {
142     qAlgorithm( QueueingAlgorithmRegistry::instance().createQAlgorithm( key));
143 }
144
145 //-/////////////////////////////////////////////////////////////////////////////////////////////////
146 #undef prefix_
147
148 \f
149 // Local Variables:
150 // mode: c++
151 // fill-column: 100
152 // comment-column: 40
153 // c-file-style: "senf"
154 // indent-tabs-mode: nil
155 // ispell-local-dictionary: "american"
156 // compile-command: "scons -u test"
157 // End::