|
xorp
|
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__