c6b0db8c30132b096be01a2fea31b5b402047e57
[senf.git] / Scheduler / Scheduler.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
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 Scheduler public header
25  */
26
27 #ifndef HH_Scheduler_
28 #define HH_Scheduler_ 1
29
30 // Custom includes
31 #include "../Utils/Logger/SenfLog.hh"
32 #include "FdEvent.hh"
33 #include "TimerEvent.hh"
34 #include "SignalEvent.hh"
35 #include "EventHook.hh"
36
37 //#include "scheduler.mpp"
38 ///////////////////////////////hh.p////////////////////////////////////////
39
40 namespace senf {
41
42 /** \brief The Scheduler interface
43
44     The %scheduler API is comprised of two parts:
45
46     \li Specific \ref sched_objects, one for each type of event.
47     \li Some <a href="#autotoc-7.">generic functions</a> implemented in the \ref senf::scheduler
48         namespace.
49
50     Events are registered via the respective event class. The (global) functions are used to enter
51     the application main-loop or query for global information.
52
53     \autotoc
54
55
56     \section sched_objects Event classes
57
58     The Scheduler is based on the RAII principle: Every event is represented by a class
59     instance. The event is registered in the constructor and removed by the destructor of that
60     instance. This implementation automatically links the lifetime of an event with the lifetime of
61     the object resposible for it's creation.
62
63     Every event registration is represented by an instance of an event specific class:
64
65     \li senf::scheduler::FdEvent for file descriptor events
66     \li senf::scheduler::TimerEvent for single-shot deadline timer events
67     \li senf::scheduler::SignalEvent for UNIX signal events
68     \li senf::scheduler::EventHook for a special event hook
69
70     These instance are owned and managed by the user of the scheduler \e not by the scheduler so the
71     RAII concept can be used.
72
73     \code
74     class SomeServer
75     {
76         SomeSocketHandle handle_;
77         senf::scheduler::FdEvent event_;
78
79     public:
80         SomeServer(SomeSocketHandle handle)
81             : handle_ (handle), 
82               event_ ("SomeServer handler", senf::membind(&SomeServer::readData, this),
83                       handle, senf::scheduler::FdEvent::EV_READ)
84         {}
85
86         void readData(int events)
87         {
88             // read data from handle_, check for eof and so on.
89         }
90     };
91     \endcode
92
93     The event is defined as a class member variable. When the event member is initialized in the
94     constructor, the event is automatically registered (except if the optional \a initiallyEnabled
95     flag argument is set to \c false). The Destructor will automatically remove the event from the
96     scheduler and ensure, that no dead code is called accidentally.
97
98     The process is the same for the other event types or when registering multiple events. For
99     detailed information on the constructor arguments and other features see the event class
100     documentation referenced below.
101
102
103     \section sched_handlers Specifying handlers
104
105     All handlers are specified as generic <a
106     href="http://www.boost.org/doc/html/function.html">Boost.Function</a> objects. This allows to
107     pass any callable as a handler. Depending on the type of handler, some additional arguments may
108     be passed to the handler by the %scheduler.
109
110     If you need to pass additional information to your handler, use <a
111     href="http://www.boost.org/libs/bind/bind.html">Boost.Bind</a>:
112     \code
113     // Handle callback function
114     void callback(UDPv4ClientSocketHandle handle, senf::Scheduler::EventId event) {..}
115     // Pass 'handle' as additional first argument to callback()
116     senf::scheduler::FdEvent event ("name", boost::bind(&callback, handle, _1), 
117                                     handle, senf::scheduler::FdEvent::EV_READ);
118      // Timeout function
119     void timeout( int n) {..}
120     // Call timeout() handler with argument 'n'
121     senf::scheduler::TimerEvent timer ("name", boost::bind(&timeout, n),
122                                        senf::ClockService::now() + senf::ClockService::seconds(1));
123     \endcode
124
125     To use member-functions as callbacks, use either <a
126     href="http://www.boost.org/libs/bind/bind.html">Boost.Bind</a> or senf::membind()
127     \code
128     // e.g. in Foo::Foo() constructor:
129     Foo::Foo()
130         : handle_ (...),
131           readevent_ ("Foo read", senf::membind(&Foo::callback, this), 
132                       handle_, senf::scheduler::FdEvent::EV_READ)
133     { ... }
134     \endcode
135
136     The handler is identified by an arbitrary, user specified name. This name is used in error
137     messages to identify the failing handler.
138
139
140     \section sched_exec Executing the Scheduler
141
142     To enter the scheduler main-loop, call
143     
144     \code
145     senf::scheduler::process();
146     \endcode
147
148     This call will only return in two cases:
149
150     \li When a handler calls senf::scheduler::terminate()
151     \li When there is no active file descriptor or timer event.
152
153     Additional <a href="#autotoc-7.">generic functions</a> provide information and %scheduler
154     parameters.
155
156     \section sched_container Event objects and container classes
157
158     As the event objects are \e not copyable, they cannot be placed into ordinary
159     containers. However, it is quite simple to use pointer containers to hold event instances:
160
161     \code
162     #include <boost/ptr_container/ptr_map.hpp>
163     #include <boost/bind.hpp>
164     
165     class Foo
166     {
167     public:
168         void add(int fd)
169         {
170             fdEvents.insert(
171                 fd, 
172                 new senf::scheduler::FdEvent("foo", boost::bind(&callback, this, fd, _1), fd, 
173                                              senf::scheduler::FdEvent::EV_READ) );
174         }
175
176         void callback(int fd, int events)
177         {
178             FdEvent & event (fdEvents_[fd]);
179
180             // ...
181
182             if (complete)
183                 fdEvents_.remove(fd)
184         }
185
186     private:
187         boost::ptr_map<int, FdEvent> fdEvents_;
188     };
189     \endcode
190
191     The pointer container API is (almost) completely identical to the corresponding standard library
192     container API. The only difference is, that all elements added to the container \e must be
193     created via \c new and that the pointer containers themselves are \e not copyable (ok, they are,
194     if the elements are cloneable ...). See <a
195     href="http://www.boost.org/doc/libs/1_36_0/libs/ptr_container/doc/ptr_container.html">Boost.PointerContainer</a>
196     for the pointer container library reference.
197
198     \todo Fix the file support to use threads (?) fork (?) and a pipe so it works reliably even
199         over e.g. NFS.
200   */
201 namespace scheduler {
202
203     /** \brief Event handler main loop 
204         
205         This member must be called at some time to enter the event handler main loop. Only while
206         this function is running any events are handled. The call will return if
207         \li a callback calls terminate()
208         \li the run queue becomes empty. 
209      */    
210     void process();                     
211
212     /** \brief Called by callbacks to terminate the main loop
213
214         This member may be called by any callback to tell the main loop to terminate. The main loop
215         will return to it's caller after the currently running callback returns. 
216      */
217     void terminate(); 
218
219     /** \brief Return timestamp of last event
220
221         This is the timestamp, the last event has been signaled. This is the real time at which the
222         event is delivered \e not the time it should have been delivered (in the case of timers). 
223      */
224     ClockService::clock_type eventTime(); 
225
226     /** \brief Set task watchdog timeout */
227     void taskTimeout(unsigned ms); 
228
229     /** \brief Current task watchdog timeout */
230     unsigned taskTimeout(); 
231
232     /** \brief Number of watchdog events */
233     unsigned hangCount(); 
234
235     /** \brief Restart scheduler
236         
237         This call will restart all scheduler dispatchers (timers, signals, file descriptors). This
238         is necessary after a fork().
239         \warning This call will \e remove all registered events from the scheduler
240      */
241     void restart(); 
242
243     /** \brief Return \c true, if any event is registered, \c false otherwise. */
244     bool empty();
245
246     /** \brief %scheduler specific time source for Utils/Logger framework
247
248         This time source may be used to provide timing information for log messages within the
249         Utils/Logger framework. This time source will use Scheduler::eventTime() to provide timing
250         information.
251
252         \code
253         senf::log::timeSource<senf::scheduler::LogTimeSource>();
254         \endcode
255
256         Using this information reduces the number of necessary ClockService::now() calls and thus
257         the number of system calls.
258      */
259     struct LogTimeSource : public senf::log::TimeSource
260     {
261         senf::log::time_type operator()() const;
262     };
263
264 }}
265
266 ///////////////////////////////hh.e////////////////////////////////////////
267 #include "Scheduler.cci"
268 //#include "Scheduler.ct"
269 //#include "Scheduler.cti"
270 #endif
271
272 \f
273 // Local Variables:
274 // mode: c++
275 // fill-column: 100
276 // c-file-style: "senf"
277 // indent-tabs-mode: nil
278 // ispell-local-dictionary: "american"
279 // compile-command: "scons -u test"
280 // comment-column: 40
281 // End: