Fixed whitespace in all files (no tabs)
[senf.git] / Scheduler / Scheduler.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.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 <map>
32 #include <queue>
33 #include <boost/function.hpp>
34 #include <boost/utility.hpp>
35 #include <boost/call_traits.hpp>
36
37 #include "Utils/MicroTime.hh"
38
39 //#include "scheduler.mpp"
40 ///////////////////////////////hh.p////////////////////////////////////////
41
42 /** \brief SENF Project namespace */
43 namespace senf {
44
45     /** \brief Singleton class to manage the event loop
46
47         This class manages a single select() type event loop. A customer of this class may register
48         any number of file descriptiors with this class and pass callback functions to be called on
49         input, output or error. This functions are specified using boost::function objects (See <a
50         href="http://www.boost.org/doc/html/function.html">Boost.Function</a>)
51
52         The Scheduler is based on a generic handle representation. The only information needed from
53         a handle, is the intrinsic file descriptor. Any object for which the statement
54         \code
55           int fd = retrieve_filehandle(object);
56         \endcode
57         is valid and places the relevent file descriptor into fd can be used as a Handle type. There
58         is an implementation of retrieve_filehandle(int) within the library to handle explicit file
59         descrptors. The <a href="../../../Socket/doc/html/index.html">Socket library</a> provides an
60         implementation of <tt>retrive_filehandle(FileHandle handle)</tt>. If you want to support
61         some other handle type, just define an apropriate \c retrieve_filehandle function <em>in
62         that types namespace</em>.
63
64         It is important to note, that for every combination of file descriptor and event, only a \e
65         single handler may be installed. Installing more handlers does not make sense. If you need
66         to distribute data to serveral interested parties, you must take care of this yourself.
67
68         \todo Fix EventId parameter (probably to int) to allow |-ing without casting ...
69       */
70     class Scheduler
71         : boost::noncopyable
72     {
73     public:
74         ///////////////////////////////////////////////////////////////////////////
75         // Types
76
77         /// \brief Types of file descriptor events */
78         enum EventId { EV_NONE=0,
79                        EV_READ=1, EV_PRIO=2, EV_WRITE=4, EV_HUP=8, EV_ERR=16,
80                        EV_ALL=31 };
81
82         /** \brief Template typedef for Callback type
83
84             This is a template typedef (which does not exist in C++) that is, a template class whose
85             sole member is a typedef symbol defining the callback type given the handle type.
86
87             The Callback is any callable object taking a \c Handle and an \c EventId as argument.
88          */
89         template <class Handle>
90         struct GenericCallback {
91             typedef boost::function<void (typename boost::call_traits<Handle>::param_type,
92                                           EventId) > Callback;
93         };
94         /** \brief Callback type for timer events */
95         typedef boost::function<void ()> TimerCallback;
96
97         ///////////////////////////////////////////////////////////////////////////
98         ///\name Structors and default members
99         ///@{
100
101         // private default constructor
102         // no copy constructor
103         // no copy assignment
104         // default destructor
105         // no conversion constructors
106
107         /** \brief Return Scheduler instance
108
109             This static member is used to access the singleton instance. This member is save to
110             return a correctly initialized Scheduler instance even if called at global construction
111             time
112
113             \implementation This static member just defines the Scheduler as a static method
114                 variable. The C++ standard then provides above guaratee. The instance will be
115                 initialized the first time, the code flow passes the variable declaration found in
116                 the instance() body.
117          */
118         static Scheduler & instance();
119
120         ///@}
121         ///////////////////////////////////////////////////////////////////////////
122
123         template <class Handle>
124         void add(Handle const & handle,
125                  typename GenericCallback<Handle>::Callback const & cb,
126                  int eventMask = EV_ALL); ///< Add file handle event callback
127                                         /**< add() will add a callback to the Scheduler. The
128                                              callbeck will be called for the given type of event on
129                                              the given  arbitrary file-descriptor or
130                                              handle-like object. If there already is a Callback
131                                              register ed for one of the events requested, the new
132                                              handler will replace the old one.
133                                              \param[in] handle file descriptor or handle providing
134                                                  the Handle interface defined above.
135                                              \param[in] cb callback
136                                              \param[in] eventMask arbitrary combination via '|'
137                                                  operator of EventId designators. */
138         template <class Handle>
139         void remove(Handle const & handle, int eventMask = EV_ALL); ///< Remove event callback
140                                         /**< remove() will remove any callback registered for any of
141                                              the given events on the given file descriptor or handle
142                                              like object.
143                                              \param[in] handle file descriptor or handle providing
144                                                  the Handle interface defined above.
145                                              \param[in] eventMask arbitrary combination via '|'
146                                                  operator of EventId designators. */
147
148         void timeout(unsigned long timeout, TimerCallback const & cb); ///< Add timeout event
149                                         /**< \param[in] timeout timeout in milliseconds
150                                              \param[in] cb callback to call after \a timeout
151                                                  milliseconds
152                                              \todo Return some kind of handle/pointer and add
153                                                  support to update or revoke a timeout */
154
155         void process();                 ///< Event handler main loop
156                                         /**< This member must be called at some time to enter the
157                                              event handler main loop. Only while this function is
158                                              running any events are handled. The call will return
159                                              only, if any callback calls terminate(). */
160         void terminate();               ///< Called by callbacks to terminate the main loop
161                                         /**< This member may be called by any callback to tell the
162                                              main loop to terminate. The main loop will return to
163                                              it's caller after the currently running callback
164                                              returns. */
165
166     protected:
167
168     private:
169         typedef boost::function<void (EventId)> SimpleCallback;
170
171         Scheduler();
172
173         void do_add(int fd, SimpleCallback const & cb, int eventMask = EV_ALL);
174         void do_remove(int fd, int eventMask = EV_ALL);
175
176         /** \brief Descriptor event specification
177             \internal */
178         struct EventSpec
179         {
180             SimpleCallback cb_read;
181             SimpleCallback cb_prio;
182             SimpleCallback cb_write;
183             SimpleCallback cb_hup;
184             SimpleCallback cb_err;
185
186             int epollMask() const;
187         };
188
189         /** \brief Timer event specification
190             \internal */
191         struct TimerSpec
192         {
193             TimerSpec() : timeout(), cb() {}
194             TimerSpec(unsigned long long timeout_, TimerCallback cb_)
195                 : timeout(timeout_), cb(cb_) {}
196
197             bool operator< (TimerSpec const & other) const
198                 { return timeout > other.timeout; }
199
200             unsigned long long timeout;
201             TimerCallback cb;
202         };
203
204         typedef std::map<int,EventSpec> FdTable;
205         typedef std::priority_queue<TimerSpec> TimerQueue;
206
207         FdTable fdTable_;
208         TimerQueue timerQueue_;
209         int epollFd_;
210         bool terminate_;
211     };
212
213     /** \brief Default file descriptor accessor
214
215         retrieve_filehandle() provides the Scheduler with support for explicit file descriptors as
216         file handle argument.
217
218         \relates Scheduler
219      */
220     int retrieve_filehandle(int fd);
221
222 }
223
224 ///////////////////////////////hh.e////////////////////////////////////////
225 #include "Scheduler.cci"
226 //#include "Scheduler.ct"
227 #include "Scheduler.cti"
228 #endif
229
230 \f
231 // Local Variables:
232 // mode: c++
233 // fill-column: 100
234 // c-file-style: "senf"
235 // indent-tabs-mode: nil
236 // ispell-local-dictionary: "american"
237 // End: