xorp

eventloop.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2001-2011 XORP, Inc and Others
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU Lesser General Public License, Version
00008 // 2.1, June 1999 as published by the Free Software Foundation.
00009 // Redistribution and/or modification of this program under the terms of
00010 // any other version of the GNU Lesser General Public License is not
00011 // permitted.
00012 // 
00013 // This program is distributed in the hope that it will be useful, but
00014 // WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00016 // see the GNU Lesser General Public License, Version 2.1, a copy of
00017 // which can be found in the XORP LICENSE.lgpl file.
00018 // 
00019 // XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00020 // http://xorp.net
00021 
00022 
00023 #ifndef __LIBXORP_EVENTLOOP_HH__
00024 #define __LIBXORP_EVENTLOOP_HH__
00025 
00026 #ifdef HAVE_SYS_TIME_H
00027 #include <sys/time.h>
00028 #endif
00029 
00030 #include "xorpfd.hh"
00031 #include "clock.hh"
00032 #include "timer.hh"
00033 #include "task.hh"
00034 #include "callback.hh"
00035 #include "ioevents.hh"
00036 
00037 #ifdef USE_WIN_DISPATCHER
00038 #include "win_dispatcher.hh"
00039 #else
00040 #include "selector.hh"
00041 #endif
00042 
00043 
00044 // The default signal handler logic will catch:
00045 // SIGTERM, SIGINT, SIGXFSZ, SIGXCPU
00046 // and set xorp_do_run to 0.  Control loops can use this
00047 // to bail out and gracefully exit.
00048 extern int xorp_do_run;
00049 extern char xorp_sig_msg_buffer[64];
00050 
00051 void setup_dflt_sighandlers();
00052 void dflt_sig_handler(int signo);
00053 
00054 
00055 extern EnvTrace eloop_trace;
00056 
00057 
00065 class EventLoop :
00066     public NONCOPYABLE
00067 {
00068 public:
00072     EventLoop();
00073 
00077     virtual ~EventLoop();
00078 
00130     void run();
00131 
00132     void set_debug(bool v) {
00133     _is_debug = v;
00134 #ifndef HOST_OS_WINDOWS
00135     _selector_list.set_debug(v);
00136 #endif
00137     }
00138 
00139     bool is_debug() const { return (_is_debug); }
00140 
00145     TimerList&    timer_list()      { return _timer_list; }
00146 
00147 #ifndef HOST_OS_WINDOWS
00148 
00153     SelectorList& selector_list()   { return _selector_list; }
00154 #endif
00155 
00164     XorpTimer new_oneoff_at(const TimeVal& when,
00165                 const OneoffTimerCallback& ocb,
00166                 int priority = XorpTask::PRIORITY_DEFAULT);
00167 
00176     XorpTimer new_oneoff_after(const TimeVal& wait,
00177                    const OneoffTimerCallback& ocb,
00178                    int priority = XorpTask::PRIORITY_DEFAULT);
00179 
00188     XorpTimer new_oneoff_after_ms(int ms, const OneoffTimerCallback& ocb,
00189                   int priority = XorpTask::PRIORITY_DEFAULT);
00190 
00192     void remove_timer(XorpTimer& t);
00193 
00203     XorpTimer new_periodic(const TimeVal& wait,
00204                const PeriodicTimerCallback& pcb,
00205                int priority = XorpTask::PRIORITY_DEFAULT);
00206 
00216     XorpTimer new_periodic_ms(int ms, const PeriodicTimerCallback& pcb,
00217                   int priority = XorpTask::PRIORITY_DEFAULT);
00218 
00230     XorpTimer set_flag_at(const TimeVal&    when,
00231               bool*         flag_ptr,
00232               bool          to_value = true);
00233 
00245     XorpTimer set_flag_after(const TimeVal&     wait,
00246                  bool*      flag_ptr,
00247                  bool       to_value = true);
00248 
00263     XorpTimer set_flag_after_ms(int ms, bool* flag_ptr, bool to_value = true);
00264 
00275     XorpTimer new_timer(const BasicTimerCallback& cb);
00276 
00287     XorpTask new_oneoff_task(const OneoffTaskCallback& cb,
00288                  int priority = XorpTask::PRIORITY_DEFAULT,
00289                  int weight = XorpTask::WEIGHT_DEFAULT);
00290 
00303     XorpTask new_task(const RepeatedTaskCallback& cb,
00304               int priority = XorpTask::PRIORITY_DEFAULT,
00305               int weight = XorpTask::WEIGHT_DEFAULT);
00306 
00327     bool add_ioevent_cb(XorpFd fd, IoEventType type, const IoEventCb& cb,
00328             int priority = XorpTask::PRIORITY_DEFAULT);
00329 
00338     bool remove_ioevent_cb(XorpFd fd, IoEventType type = IOT_ANY);
00339 
00343     bool timers_pending() const;
00344 
00349     bool events_pending() const;
00350 
00354     size_t timer_list_length() const;
00355 
00359     void current_time(TimeVal& now) const;
00360 
00366     size_t descriptor_count() const;
00367 
00368     void set_aggressiveness(int num);
00369 
00370 private:
00371     void do_work();
00372 
00373 private:
00374     ClockBase*      _clock;
00375     TimerList       _timer_list;
00376     TaskList        _task_list;
00377     int         _aggressiveness;
00378     time_t      _last_ev_run;   // 0 - Means run not called yet.
00379     time_t      _last_warned;
00380     bool        _is_debug;  // If true, debug enabled
00381     // Was the last event at this priority a selector or a task.
00382     bool        _last_ev_type[XorpTask::PRIORITY_INFINITY]; 
00383 #if USE_WIN_DISPATCHER
00384     WinDispatcher   _win_dispatcher;
00385 #else
00386     SelectorList    _selector_list;
00387 #endif
00388 };
00389 
00390 // ----------------------------------------------------------------------------
00391 // Deferred definitions
00392 
00393 inline XorpTimer
00394 EventLoop::new_timer(const BasicTimerCallback& cb)
00395 {
00396     return _timer_list.new_timer(cb);
00397 }
00398 
00399 inline XorpTimer
00400 EventLoop::new_oneoff_at(const TimeVal& tv, const OneoffTimerCallback& ocb,
00401              int priority)
00402 {
00403     return _timer_list.new_oneoff_at(tv, ocb, priority);
00404 }
00405 
00406 inline XorpTimer
00407 EventLoop::new_oneoff_after(const TimeVal& wait,
00408                 const OneoffTimerCallback& ocb,
00409                 int priority)
00410 {
00411     return _timer_list.new_oneoff_after(wait, ocb, priority);
00412 }
00413 
00414 inline XorpTimer
00415 EventLoop::new_oneoff_after_ms(int ms, const OneoffTimerCallback& ocb,
00416                    int priority)
00417 {
00418     TimeVal wait(ms / 1000, (ms % 1000) * 1000);
00419     return _timer_list.new_oneoff_after(wait, ocb, priority);
00420 }
00421 
00422 inline XorpTimer
00423 EventLoop::new_periodic(const TimeVal& wait, const PeriodicTimerCallback& pcb,
00424             int priority)
00425 {
00426     return _timer_list.new_periodic(wait, pcb, priority);
00427 }
00428 
00429 inline XorpTimer
00430 EventLoop::new_periodic_ms(int ms, const PeriodicTimerCallback& pcb,
00431                int priority)
00432 {
00433     TimeVal wait(ms / 1000, (ms % 1000) * 1000);
00434     return _timer_list.new_periodic(wait, pcb, priority);
00435 }
00436 
00437 inline XorpTimer
00438 EventLoop::set_flag_at(const TimeVal& tv, bool *flag_ptr, bool to_value)
00439 {
00440     return _timer_list.set_flag_at(tv, flag_ptr, to_value);
00441 }
00442 
00443 inline XorpTimer
00444 EventLoop::set_flag_after(const TimeVal& wait, bool *flag_ptr, bool to_value)
00445 {
00446     return _timer_list.set_flag_after(wait, flag_ptr, to_value);
00447 }
00448 
00449 inline XorpTimer
00450 EventLoop::set_flag_after_ms(int ms, bool *flag_ptr, bool to_value)
00451 {
00452     TimeVal wait(ms / 1000, (ms % 1000) * 1000);
00453     return _timer_list.set_flag_after(wait, flag_ptr, to_value);
00454 }
00455 
00456 inline bool
00457 EventLoop::timers_pending() const
00458 {
00459     return !_timer_list.empty();
00460 }
00461 
00462 inline bool
00463 EventLoop::events_pending() const
00464 {
00465     return ((!_timer_list.empty()) || (!_task_list.empty()));
00466 }
00467 
00468 inline size_t
00469 EventLoop::timer_list_length() const
00470 {
00471     return _timer_list.size();
00472 }
00473 
00474 inline void
00475 EventLoop::current_time(TimeVal& t) const
00476 {
00477     _timer_list.current_time(t);
00478 }
00479 
00480 #endif // __LIBXORP_EVENTLOOP_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations