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