// $Id$
//
// Copyright (C) 2006
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
#include <boost/call_traits.hpp>
#include <boost/integer.hpp>
#include "ClockService.hh"
-#include "../Utils/Logger/Target.hh"
+#include "../Utils/Logger/SenfLog.hh"
//#include "scheduler.mpp"
///////////////////////////////hh.p////////////////////////////////////////
are defined on top of this functionality (e.g. ReadHelper or WriteHelper or the interval
timers of the PPI).
- \section sched_handlers Handlers
- All handlers are managed as generic <a
+ \section sched_handlers Specifying handlers
+
+ All handlers are passed as generic <a
href="http://www.boost.org/doc/html/function.html">Boost.Function</a> objects. This allows
to pass any callable as a handler. Depending on the type of handler, some additional
- arguments may be passed to the handler by the scheduler. If you want to pass additional
- arguments to the handler, use <a
- href="http://www.boost.org/libs/bind/bind.html">Boost.Bind</a>)).
+ arguments may be passed to the handler by the scheduler.
+
+ If you need to pass additional information to your handler, use <a
+ href="http://www.boost.org/libs/bind/bind.html">Boost.Bind</a>:
+ \code
+ // Pass 'handle' as additional first argument to callback()
+ Scheduler::instance().add(handle, boost::bind(&callback, handle, _1))
+ // Call timeout() handler with argument 'n'
+ Scheduler::instance().timeout(boost::bind(&timeout, n))
+ \endcode
+
+ To use member-functions as callbacks, use either <a
+ href="http://www.boost.org/libs/bind/bind.html">Boost.Bind</a> or senf::membind()
+ \code
+ // e.g. in Foo::Foo() constructor:
+ Scheduler::instance().add(handle_, senf::membind(&Foo::callback, this))
+ \endcode
- \section sched_fd File descriptors
+ \section sched_fd Registering file descriptors
File descriptors are managed using add() or remove()
\code
Scheduler::instance().add(handle, &callback);
Scheduler::instance().remove(handle);
- \endcode
+ \endcode
+
The callback will be called with one additional argument. This argument is the event mask of
- type EventId. This mask will tell, which of the registered events are
- signaled. Additionally, EV_HUP or EV_ERR on hangup or error condition on the handle.
+ type EventId. This mask will tell, which of the registered events are signaled. The
+ additional flags EV_HUP or EV_ERR (on hangup or error condition) may be set additionally.
- There is always only one handler registered for a file descriptor (registering multiple
- callbacks for a single fd does not make sense).
+ Only a single handler may be registered for any combination of file descriptor and event
+ (registering multiple callbacks for a single fd and event does not make sense).
- The scheduler will accept an almost arbitrary object as it's first argument. It will use
+ The scheduler will accept any object as \a handle argument as long as retrieve_filehandle()
+ may be called on that object
\code
int fd = retrieve_filehandle(handle);
- \endcode
- To fetch the file handle given some abstract handle type. The definition of
- retrieve_filehandle() will be found using ADL.
+ \endcode
+ to fetch the file handle given some abstract handle type. retrieve_filehandle() will be
+ found using ADL depending on the argument namespace. A default implementation is provided
+ for \c int arguments (file descriptors)
- \section sched_timers Timers
+ \section sched_timers Registering timers
The Scheduler has very simple timer support. There is only one type of timer: A single-shot
deadline timer. More complex timers are built based on this. Timers are managed using
timeoutEarly. By default, this value is set to 0 but may be changed if needed.
- \section sched_signals POSIX/UNIX signals
+ \section sched_signals Registering POSIX/UNIX signals
The Scheduler also incorporates standard POSIX/UNIX signals. Signals registered with the
scheduler will be handled \e synchronously within the event loop.
wait for signals \e only.
\todo Fix EventId parameter (probably to int) to allow |-ing without casting ...
+
+ \todo Fix the file support to use threads (?) fork (?) and a pipe so it works reliably even
+ over e.g. NFS.
*/
class Scheduler
: boost::noncopyable
{
public:
+
+ SENF_LOG_CLASS_AREA();
+
///////////////////////////////////////////////////////////////////////////
// Types
sole member is a typedef symbol defining the callback type given the handle type.
The Callback is any callable object taking a \c Handle and an \c EventId as argument.
- template <class Handle>
- struct GenericCallback {
- typedef boost::function<void (typename boost::call_traits<Handle>::param_type,
- EventId) > Callback;
- };
+ \code
+ template <class Handle>
+ struct GenericCallback {
+ typedef boost::function<void (typename boost::call_traits<Handle>::param_type,
+ EventId) > Callback;
+ };
+ \endcode
*/
-
typedef boost::function<void (EventId)> FdCallback;
/** \brief Callback type for timer events */
void unregisterSignal(unsigned signal);
///< Remove signal handler for \a signal
+ /// The signal number passed to registerSignal or unregisterSignal is invalid
struct InvalidSignalNumberException : public std::exception
{ virtual char const * what() const throw()
{ return "senf::Scheduler::InvalidSignalNumberException"; } };
FdCallback cb_prio;
FdCallback cb_write;
+ EventSpec() : file(false) {}
+
int epollMask() const;
+
+ bool file;
};
/** \brief Timer event specification
typedef std::map<int,EventSpec> FdTable;
typedef std::map<unsigned,TimerSpec> TimerMap; // sorted by id
+ typedef std::vector<unsigned> FdEraseList;
# ifndef DOXYGEN
typedef std::vector<SimpleCallback> SigHandlers;
FdTable fdTable_;
+ FdEraseList fdErase_;
+ unsigned files_;
unsigned timerIdCounter_;
TimerQueue timerQueue_;