The scheduler API is comprised of two parts:
Every event registration is represented by an instance of an event specific class:
class SomeServer { SomeSocketHandle handle_; senf::scheduler::FdEvent event_; public: SomeServer(SomeSocketHandle handle) : handle_ (handle), event_ ("SomeServer handler", senf::membind(&SomeServer::readData, this), handle, senf::scheduler::FdEvent::EV_READ) {} void readData(int events) { // read data from handle_, check for eof and so on. } };
The event is defined as a class member variable. When the event member is initialized in the constructor, the event is automatically registered (except if the optional initiallyEnabled flag argument is set to false
). The Destructor will automatically remove the event from the scheduler and ensure, that no dead code is called accidentally.
The process is the same for the other event types or when registering multiple events. For detailed information on the constructor arguments and other features see the event class documentation referenced below.
If you need to pass additional information to your handler, use Boost.Bind:
// Handle callback function void callback(UDPv4ClientSocketHandle handle, senf::Scheduler::EventId event) {..} // Pass 'handle' as additional first argument to callback() senf::scheduler::FdEvent event ("name", boost::bind(&callback, handle, _1), handle, senf::scheduler::FdEvent::EV_READ); // Timeout function void timeout( int n) {..} // Call timeout() handler with argument 'n' senf::scheduler::TimerEvent timer ("name", boost::bind(&timeout, n), senf::ClockService::now() + senf::ClockService::seconds(1));
To use member-functions as callbacks, use either Boost.Bind or senf::membind()
// e.g. in Foo::Foo() constructor: Foo::Foo() : handle_ (...), readevent_ ("Foo read", senf::membind(&Foo::callback, this), handle_, senf::scheduler::FdEvent::EV_READ) { ... }
The handler is identified by an arbitrary, user specified name. This name is used in error messages to identify the failing handler.
This call will only return in two cases:
#include <boost/ptr_container/ptr_map.hpp> #include <boost/bind.hpp> class Foo { public: void add(int fd) { fdEvents.insert( fd, new senf::scheduler::FdEvent("foo", boost::bind(&callback, this, fd, _1), fd, senf::scheduler::FdEvent::EV_READ) ); } void callback(int fd, int events) { FdEvent & event (fdEvents_[fd]); // ... if (complete) fdEvents_.remove(fd) } private: boost::ptr_map<int, FdEvent> fdEvents_; };
The pointer container API is (almost) completely identical to the corresponding standard library container API. The only difference is, that all elements added to the container must be created via new
and that the pointer containers themselves are not copyable (ok, they are, if the elements are cloneable ...). See Boost.PointerContainer for the pointer container library reference.
The watchdog is controlled using the watchdogTimeout(), watchdogEvents() and watchdogAbort(). functions.
The watchdog is implemented using a free running interval timer. The watchdog signal (SIGURG
) must not be blocked. If signals need to be blocked for some reason, those regions will not be checked by the watchdog. If a callback blocks, the watchdog has no chance to interrupt the process.
SIGALRM
) may occur when using using hires timers on kernel/glibc combinations which do not support timerfd(). On such systems, hires timers are implemented using POSIX timers which generate a considerable number of additional signals.
6. Namespaces |
|
namespace | detail |
7. Classes |
|
class | EventHook |
Event hook event. More... |
|
class | FdEvent |
File descriptor event. More... |
|
class | IdleEvent |
struct | LogTimeSource |
scheduler specific time source for Utils/Logger framework More... |
|
class | BlockSignals |
Temporarily block all signals. More... |
|
class | SignalEvent |
UNIX signal event. More... |
|
class | TimerEvent |
Deadline timer event. More... |
|
class | TimerEventProxy |
Deadline timer proxy. More... |
|
8. Functions |
|
ClockService::clock_type | now () |
Return (approximate) current time. |
|
console::ScopedDirectory & | consoleDir () |
void | restart () |
Restart scheduler. |
|
template<class Handle > | |
int | get_descriptor (Handle const &handle) |
Get file descriptor from handle object. |
|
void | process () |
Event handler main loop. |
|
bool | running () |
true , if scheduler is running, false otherwise |
|
void | terminate () |
Called by callbacks to terminate the main loop. |
|
void | yield () |
Immediately rescheduler. |
|
ClockService::clock_type | eventTime () |
Return timestamp of last event. |
|
void | watchdogTimeout (unsigned ms) |
Set watchdog timeout to ms milliseconds. |
|
unsigned | watchdogTimeout () |
Current watchdog timeout in milliseconds. |
|
unsigned | watchdogEvents () |
Number of watchdog events. |
|
void | watchdogAbort (bool flag) |
Enable/disable abort on watchdog event. |
|
bool | watchdogAbort () |
Get current watchdog abort on event status. |
|
void | hiresTimers () |
Switch to using hi resolution timers. |
|
void | loresTimers () |
Switch back to using epoll for timing. |
|
bool | haveScalableHiresTimers () |
return true , if timerfd() timing is available, false otherwise |
|
bool | usingHiresTimers () |
Return true , if using hires times, false otherwise. |
|
bool | empty () |
Return true , if no event is registered, false otherwise. |
senf::console::ScopedDirectory & senf::scheduler:: | ||||
consoleDir | () | |||
Definition at line 36 of file ConsoleDir.cc.
bool senf::scheduler:: | ||||
empty | () | |||
Return true
, if no event is registered, false
otherwise.
Definition at line 140 of file Scheduler.cc.
senf::ClockService::clock_type senf::scheduler:: | ||||
eventTime | () | |||
Return timestamp of last event.
This is the timestamp, the last event has been signaled. This is the real time at which the event is delivered not the time it should have been delivered (in the case of timers).
Definition at line 37 of file Scheduler.cci.
int senf::scheduler:: | ||||
get_descriptor | ( | Handle const & | handle | ) |
Get file descriptor from handle object.
This function will query the handle for it's file descriptor. The real implementation must be provided by a freestanding function retrieve_filehandle(Handle const & h)
within the namespace of Handle.
Definition at line 50 of file FdEvent.cti.
bool senf::scheduler:: | ||||
haveScalableHiresTimers | () | |||
return true
, if timerfd()
timing is available, false
otherwise
Definition at line 73 of file Scheduler.cci.
void senf::scheduler:: | ||||
hiresTimers | () | |||
Switch to using hi resolution timers.
By default, timers are implemented directly using epoll. This however restricts the timer resolution to that of the kernel HZ value.
High resolution timers are implemented either using POSIX timers or, when available, using the Linux special timerfd()
syscall.
POSIX timers are delivered using signals. A high timer load this increases the signal load considerably. timerfd()'s
are delivered on a file descriptor and thus don't have such a scalability issue.
Definition at line 150 of file Scheduler.cc.
void senf::scheduler:: | ||||
loresTimers | () | |||
Switch back to using epoll for timing.
Definition at line 67 of file Scheduler.cci.
ClockService::clock_type senf::scheduler:: | ||||
now | () | |||
Return (approximate) current time.
This call will return the current time as far as it is already known to the scheduler. If the scheduler is running, this will return eventTime(), otherwise it will return ClockService::now(). While the scheduler is running, this will reduce the number of system calls.
Definition at line 62 of file Scheduler.cc.
void senf::scheduler:: | ||||
process | () | |||
Event handler main loop.
This member must be called at some time to enter the event handler main loop. Only while this function is running any events are handled. The call will return if
Definition at line 91 of file Scheduler.cc.
void senf::scheduler:: | ||||
restart | () | |||
Restart scheduler.
This call will restart all scheduler dispatchers (timers, signals, file descriptors). This is necessary after a fork().
Definition at line 110 of file Scheduler.cc.
bool senf::scheduler:: | ||||
running | () | |||
true
, if scheduler is running, false
otherwise
Definition at line 57 of file Scheduler.cc.
void senf::scheduler:: | ||||
terminate | () | |||
Called by callbacks to terminate the main loop.
This member may be called by any callback to tell the main loop to terminate. The main loop will return to it's caller after the currently running callback returns.
Definition at line 47 of file Scheduler.cc.
bool senf::scheduler:: | ||||
usingHiresTimers | () | |||
Return true
, if using hires times, false
otherwise.
Definition at line 82 of file Scheduler.cci.
bool senf::scheduler:: | ||||
watchdogAbort | () | |||
Get current watchdog abort on event status.
Definition at line 62 of file Scheduler.cci.
void senf::scheduler:: | ||||
watchdogAbort | ( | bool | flag | ) |
Enable/disable abort on watchdog event.
Calling watchdogAbort(true
) will enable aborting the program execution on a watchdog event.
Definition at line 57 of file Scheduler.cci.
unsigned senf::scheduler:: | ||||
watchdogEvents | () | |||
Number of watchdog events.
calling watchtogEvents() will reset the counter to 0
Definition at line 52 of file Scheduler.cci.
unsigned senf::scheduler:: | ||||
watchdogTimeout | () | |||
Current watchdog timeout in milliseconds.
Definition at line 47 of file Scheduler.cci.
void senf::scheduler:: | ||||
watchdogTimeout | ( | unsigned | ms | ) |
Set watchdog timeout to ms milliseconds.
Setting the watchdog timeout to 0 will disable the watchdog.
Definition at line 42 of file Scheduler.cci.
void senf::scheduler:: | ||||
yield | () | |||
Immediately rescheduler.
Calling yield() will cause the scheduler to terminate the current queue run and immediately rescheduler all pending tasks.
Definition at line 52 of file Scheduler.cc.