Lines Matching +full:timer +full:-
29 #include "utils/signals/timer.hpp"
64 /// Calls setitimer(2) with exception-based error reporting.
68 /// \param delta The time to the first activation of the programmed timer.
70 /// existing system timer.
81 if (::setitimer(ITIMER_REAL, &timeval, old_timeval) == -1) { in safe_setitimer()
83 throw signals::system_error("Failed to program system's interval timer", in safe_setitimer()
89 /// Deadline scheduler for all user timers on top of the unique system timer.
95 typedef std::set< signals::timer* > timers_set;
98 typedef std::vector< signals::timer* > timers_vector;
103 /// sequentially to find either expired or expiring-now timers.
106 /// The original timer before any timer was programmed.
112 /// Time of the current activation of the timer.
118 /// Adds a timer to the _all_timers map.
120 /// \param timer The timer to add.
122 add_to_all_timers(signals::timer* timer) in add_to_all_timers() argument
124 timers_set& timers = _all_timers[timer->when()]; in add_to_all_timers()
125 INV(timers.find(timer) == timers.end()); in add_to_all_timers()
126 timers.insert(timer); in add_to_all_timers()
129 /// Removes a timer from the _all_timers map.
132 /// removal of the timer causes its bucket to be emptied.
134 /// \param timer The timer to remove.
136 remove_from_all_timers(signals::timer* timer) in remove_from_all_timers() argument
138 // We may not find the timer in _all_timers if the timer has fired, in remove_from_all_timers()
141 timer->when()); in remove_from_all_timers()
144 INV(timers.find(timer) != timers.end()); in remove_from_all_timers()
145 timers.erase(timer); in remove_from_all_timers()
185 /// Adjusts the global system timer to point to the next activation.
198 // leave the global timer as is. in reprogram_system_timer()
224 const datetime::delta delta = next - now; in reprogram_system_timer()
225 LD(F("Reprogramming timer; firing on %s; now is %s") % next % now); in reprogram_system_timer()
232 /// Programs the first timer.
234 /// The programming of the first timer involves setting up the SIGALRM
235 /// handler and installing a timer handler for the first time, which in turn
238 /// \param timer The timer being programmed.
242 global_state(signals::timer* timer, const datetime::timestamp& now) : in global_state() argument
243 _timer_activation(timer->when()) in global_state()
245 PRE(now < timer->when()); in global_state()
249 const datetime::delta delta = timer->when() - now; in global_state()
250 LD(F("Installing first timer; firing on %s; now is %s") % in global_state()
251 timer->when() % now); in global_state()
257 _timer_activation = timer->when(); in global_state()
258 add_to_all_timers(timer); in global_state()
267 /// This clears the global system timer and unsets the SIGALRM handler.
274 if (::setitimer(ITIMER_REAL, &_old_timeval, NULL) == -1) { in ~global_state()
275 UNREACHABLE_MSG("Failed to restore original timer"); in ~global_state()
278 _sigalrm_programmer->unprogram(); in ~global_state()
282 /// Programs a new timer, possibly adjusting the global system timer.
284 /// Programming any timer other than the first one only involves reloading
285 /// the existing timer, not backing up the previous handler nor installing a
288 /// \param timer The timer being programmed.
293 program_new(signals::timer* timer, const datetime::timestamp& now) in program_new() argument
297 add_to_all_timers(timer); in program_new()
301 /// Unprograms a timer.
303 /// This removes the timer from the global state and reprograms the global
304 /// system timer if necessary.
306 /// \param timer The timer to unprogram.
308 /// \return True if the system interval timer has been reprogrammed to
309 /// another future timer; false if there are no more active timers.
311 unprogram(signals::timer* timer) in unprogram() argument
315 LD(F("Unprogramming timer; previously firing on %s") % timer->when()); in unprogram()
317 remove_from_all_timers(timer); in unprogram()
353 /// SIGALRM handler for the timer implementation.
360 globals->fire(datetime::timestamp::now()); in sigalrm_handler()
367 /// Indirection to invoke the private do_fired() method of a timer.
369 /// \param timer The timer on which to run do_fired().
371 utils::signals::detail::invoke_do_fired(timer* timer) in invoke_do_fired() argument
373 timer->do_fired(); in invoke_do_fired()
377 /// Internal implementation for the timer.
379 /// We assume that there is a 1-1 mapping between timer objects and impl
381 /// module breaks as well because we use pointers to the parent timer as the
382 /// identifier of the timer.
383 struct utils::signals::timer::impl : utils::noncopyable {
384 /// Timestamp when this timer is expected to fire.
386 /// Note that the timer might be processed after this timestamp, so users of
394 /// Whether this timer has fired already or not.
402 /// \param when_ Timestamp when this timer is expected to fire.
414 /// Constructor; programs a run-once timer.
416 /// This programs the global timer and signal handler if this is the first timer
417 /// being installed. Otherwise, reprograms the global timer if this timer
420 /// \param delta The time until the timer fires.
421 signals::timer::timer(const datetime::delta& delta) in timer() function in signals::timer
430 globals->program_new(this, now); in timer()
435 /// Destructor; unprograms the timer if still programmed.
440 signals::timer::~timer(void) in ~timer()
444 if (_pimpl->programmed) { in ~timer()
445 LW("Auto-destroying still-programmed signals::timer object"); in ~timer()
453 if (!_pimpl->fired) { in ~timer()
455 if (now > _pimpl->when) { in ~timer()
456 LW("Expired timer never fired; the code never called unprogram()!"); in ~timer()
462 /// Returns the time of the timer activation.
465 /// the future or in the past) nor the timer's activation status.
467 signals::timer::when(void) const in when()
469 return _pimpl->when; in when()
473 /// Callback for the SIGALRM handler when this timer expires.
478 signals::timer::do_fired(void) in do_fired()
480 PRE(!_pimpl->fired); in do_fired()
481 _pimpl->fired = true; in do_fired()
486 /// User-provided callback to run when the timer expires.
488 /// The default callback does nothing. We record the activation of the timer
494 signals::timer::callback(void) in callback()
500 /// Checks whether the timer has fired already or not.
502 /// \return Returns true if the timer has fired.
504 signals::timer::fired(void) const in fired()
506 return _pimpl->fired; in fired()
510 /// Unprograms the timer.
512 /// \pre The timer is programmed (i.e. this can only be called once).
514 /// \post If the timer never fired asynchronously because the signal delivery
515 /// did not arrive on time, make sure we invoke the timer's callback here.
517 /// \throw system_error If unprogramming the timer failed.
519 signals::timer::unprogram(void) in unprogram()
523 if (!_pimpl->programmed) { in unprogram()
524 // We cannot assert that the timer is not programmed because it might in unprogram()
527 LD("Called unprogram on already-unprogrammed timer; possibly just " in unprogram()
532 if (!globals->unprogram(this)) { in unprogram()
535 _pimpl->programmed = false; in unprogram()
537 // Handle the case where the timer has expired before we ever got its in unprogram()
539 if (!_pimpl->fired) { in unprogram()
541 if (now > _pimpl->when) { in unprogram()
542 LW(F("Firing expired timer on destruction (was to fire on %s)") % in unprogram()
543 _pimpl->when); in unprogram()