From f26d0b12c0950dc21eb5e68ea488f2a73515c6b3 Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Wed, 5 Jul 2017 21:04:36 +0100 Subject: [PATCH] Dasynq: merge changes from upstream. --- src/dasynq/dasynq-itimer.h | 31 +++++++++++++++++++++++-------- src/dasynq/dasynq-timerfd.h | 9 ++++++--- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/dasynq/dasynq-itimer.h b/src/dasynq/dasynq-itimer.h index d2599fb..99f360f 100644 --- a/src/dasynq/dasynq-itimer.h +++ b/src/dasynq/dasynq-itimer.h @@ -34,7 +34,7 @@ template class ITimerEvents : public timer_base // if there are no active timers). void set_timer_from_queue() { - struct timespec newtime; + time_val newtime; struct itimerval newalarm; if (timer_queue.empty()) { newalarm.it_value = {0, 0}; @@ -47,14 +47,30 @@ template class ITimerEvents : public timer_base struct timespec curtime; get_curtime(curtime); - newalarm.it_interval = {0, 0}; - newalarm.it_value.tv_sec = newtime.tv_sec - curtime.tv_sec; - newalarm.it_value.tv_usec = (newtime.tv_nsec - curtime.tv_nsec) / 1000; + time_val curtimev = curtime; - if (newalarm.it_value.tv_usec < 0) { - newalarm.it_value.tv_usec += 1000000; - newalarm.it_value.tv_sec--; + newalarm.it_interval = {0, 0}; + if (curtimev < newtime) { + newalarm.it_value.tv_sec = newtime.seconds() - curtime.tv_sec; + if (curtimev.nseconds() > newtime.nseconds()) { + newalarm.it_value.tv_usec = (1000000000 - curtimev.nseconds() + + newtime.nseconds()) / 1000; + newalarm.it_value.tv_sec--; + } + else { + newalarm.it_value.tv_usec = (newtime.nseconds() - curtime.tv_nsec) / 1000; + } } + else { + // We passed the timeout: set alarm to expire immediately (we must use {0,1} as + // {0,0} disables the timer). + // TODO: it would be better if we just processed the appropriate timers here, + // but that is complicated to get right especially if the event loop + // is multi-threaded. + newalarm.it_value.tv_sec = 0; + newalarm.it_value.tv_usec = 1; + } + setitimer(ITIMER_REAL, &newalarm, nullptr); } @@ -73,7 +89,6 @@ template class ITimerEvents : public timer_base // arm timerfd with timeout from head of queue set_timer_from_queue(); - // loop_mech.rearmSignalWatch_nolock(SIGALRM); return false; // don't disable signal watch } else { diff --git a/src/dasynq/dasynq-timerfd.h b/src/dasynq/dasynq-timerfd.h index d92ab0f..032c5da 100644 --- a/src/dasynq/dasynq-timerfd.h +++ b/src/dasynq/dasynq-timerfd.h @@ -155,10 +155,8 @@ template class TimerFdEvents : public timer_base void removeTimer_nolock(timer_handle_t &timer_id, clock_type clock = clock_type::MONOTONIC) noexcept { + stop_timer_nolock(timer_id, clock); timer_queue_t & queue = get_queue(clock); - if (queue.is_queued(timer_id)) { - queue.remove(timer_id); - } queue.deallocate(timer_id); } @@ -171,8 +169,13 @@ template class TimerFdEvents : public timer_base void stop_timer_nolock(timer_handle_t &timer_id, clock_type clock = clock_type::MONOTONIC) noexcept { timer_queue_t & queue = get_queue(clock); + int fd = (clock == clock_type::MONOTONIC) ? timerfd_fd : systemtime_fd; if (queue.is_queued(timer_id)) { + bool was_first = (&timer_queue.get_root()) == &timer_id; queue.remove(timer_id); + if (was_first) { + set_timer_from_queue(fd, queue); + } } } -- 2.25.1