4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <stefan.bund@fokus.fraunhofer.de>
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.
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.
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.
24 \brief Scheduler public header
28 #define HH_Scheduler_ 1
33 #include <boost/function.hpp>
34 #include <boost/utility.hpp>
35 #include <boost/call_traits.hpp>
36 #include <boost/integer.hpp>
37 #include "ClockService.hh"
38 #include "../Utils/Logger/Target.hh"
40 //#include "scheduler.mpp"
41 ///////////////////////////////hh.p////////////////////////////////////////
43 /** \brief SENF Project namespace */
46 /** \brief Singleton class to manage the event loop
48 This class manages a single select() type event loop. A customer of this class may register
49 any number of file descriptors with this class and pass callback functions to be called on
50 input, output or error. This functions are specified using boost::function objects (See <a
51 href="http://www.boost.org/doc/html/function.html">Boost.Function</a>)
53 The Scheduler is based on a generic handle representation. The only information needed from
54 a handle, is the intrinsic file descriptor. Any object for which the statement
56 int fd = retrieve_filehandle(object);
58 is valid and places the relevant file descriptor into fd can be used as a Handle type. There
59 is an implementation of retrieve_filehandle(int) within the library to handle explicit file
60 descriptors. The <a href="../../../Socket/doc/html/index.html">Socket library</a> provides an
61 implementation of <tt>retrieve_filehandle(FileHandle handle)</tt>. If you want to support
62 some other handle type, just define an appropriate \c retrieve_filehandle function <em>in
63 that types namespace</em>.
65 It is important to note, that for every combination of file descriptor and event, only a \e
66 single handler may be installed. Installing more handlers does not make sense. If you need
67 to distribute data to several interested parties, you must take care of this yourself.
69 \todo Fix EventId parameter (probably to int) to allow |-ing without casting ...
75 ///////////////////////////////////////////////////////////////////////////
78 /** \brief Types of file descriptor events */
79 enum EventId { EV_NONE=0,
80 EV_READ=1, EV_PRIO=2, EV_WRITE=4,
82 EV_HUP=8, EV_ERR=16 };
84 /** \brief Template typedef for Callback type
86 This is a template typedef (which does not exist in C++) that is, a template class whose
87 sole member is a typedef symbol defining the callback type given the handle type.
89 The Callback is any callable object taking a \c Handle and an \c EventId as argument.
91 template <class Handle>
92 struct GenericCallback {
93 typedef boost::function<void (typename boost::call_traits<Handle>::param_type,
97 /** \brief Callback type for timer events */
98 typedef boost::function<void ()> TimerCallback;
100 ///////////////////////////////////////////////////////////////////////////
101 ///\name Structors and default members
104 // private default constructor
105 // no copy constructor
106 // no copy assignment
107 // default destructor
108 // no conversion constructors
110 /** \brief Return Scheduler instance
112 This static member is used to access the singleton instance. This member is save to
113 return a correctly initialized Scheduler instance even if called at global construction
116 \implementation This static member just defines the Scheduler as a static method
117 variable. The C++ standard then provides above guarantee. The instance will be
118 initialized the first time, the code flow passes the variable declaration found in
121 static Scheduler & instance();
124 ///////////////////////////////////////////////////////////////////////////
126 template <class Handle>
127 void add(Handle const & handle,
128 typename GenericCallback<Handle>::Callback const & cb,
129 int eventMask = EV_ALL); ///< Add file handle event callback
130 /**< add() will add a callback to the Scheduler. The
131 callback will be called for the given type of event on
132 the given arbitrary file-descriptor or
133 handle-like object. If there already is a Callback
134 registered for one of the events requested, the new
135 handler will replace the old one.
136 \param[in] handle file descriptor or handle providing
137 the Handle interface defined above.
138 \param[in] cb callback
139 \param[in] eventMask arbitrary combination via '|'
140 operator of EventId designators. */
141 template <class Handle>
142 void remove(Handle const & handle, int eventMask = EV_ALL); ///< Remove event callback
143 /**< remove() will remove any callback registered for any of
144 the given events on the given file descriptor or handle
146 \param[in] handle file descriptor or handle providing
147 the Handle interface defined above.
148 \param[in] eventMask arbitrary combination via '|'
149 operator of EventId designators. */
151 unsigned timeout(ClockService::clock_type timeout, TimerCallback const & cb);
152 ///< Add timeout event
153 /**< \param[in] timeout timeout in nanoseconds
154 \param[in] cb callback to call after \a timeout
157 void cancelTimeout(unsigned id);
159 void process(); ///< Event handler main loop
160 /**< This member must be called at some time to enter the
161 event handler main loop. Only while this function is
162 running any events are handled. The call will return
163 only, if any callback calls terminate(). */
164 void terminate(); ///< Called by callbacks to terminate the main loop
165 /**< This member may be called by any callback to tell the
166 main loop to terminate. The main loop will return to
167 it's caller after the currently running callback
170 ClockService::clock_type eventTime() const; ///< Return date/time of last event
175 typedef boost::function<void (EventId)> SimpleCallback;
179 void do_add(int fd, SimpleCallback const & cb, int eventMask = EV_ALL);
180 void do_remove(int fd, int eventMask = EV_ALL);
182 /** \brief Descriptor event specification
186 SimpleCallback cb_read;
187 SimpleCallback cb_prio;
188 SimpleCallback cb_write;
190 int epollMask() const;
193 /** \brief Timer event specification
197 TimerSpec() : timeout(), cb() {}
198 TimerSpec(ClockService::clock_type timeout_, TimerCallback cb_, unsigned id_)
199 : timeout(timeout_), cb(cb_), id(id_), canceled(false) {}
201 bool operator< (TimerSpec const & other) const
202 { return timeout > other.timeout; }
204 ClockService::clock_type timeout;
210 typedef std::map<int,EventSpec> FdTable;
211 typedef std::map<unsigned,TimerSpec> TimerMap; // sorted by id
213 struct TimerSpecCompare
215 typedef TimerMap::iterator first_argument_type;
216 typedef TimerMap::iterator second_argument_type;
217 typedef bool result_type;
219 result_type operator()(first_argument_type a, second_argument_type b);
222 typedef std::priority_queue<TimerMap::iterator, std::vector<TimerMap::iterator>,
223 TimerSpecCompare> TimerQueue; // sorted by time
226 unsigned timerIdCounter_;
227 TimerQueue timerQueue_;
231 ClockService::clock_type eventTime_;
234 /** \brief Default file descriptor accessor
236 retrieve_filehandle() provides the Scheduler with support for explicit file descriptors as
237 file handle argument.
241 int retrieve_filehandle(int fd);
243 /** \brief Scheduler specific time source for Utils/Logger framework
245 This time source may be used to provide timing information for log messages within the
246 Utils/Logger framework. This time source will use Scheduler::eventTime() to provide timing
249 struct SchedulerLogTimeSource : public senf::log::TimeSource
251 boost::posix_time::ptime operator()() const;
256 ///////////////////////////////hh.e////////////////////////////////////////
257 #include "Scheduler.cci"
258 //#include "Scheduler.ct"
259 #include "Scheduler.cti"
266 // c-file-style: "senf"
267 // indent-tabs-mode: nil
268 // ispell-local-dictionary: "american"
269 // compile-command: "scons -u test"
270 // comment-column: 40