summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <mk@cm4all.com>2019-03-05 22:06:09 +0100
committerMax Kellermann <max@musicpd.org>2020-10-18 19:58:42 +0200
commit7d502fb448be74919aedb2ef895cc0f656898871 (patch)
treed2cb27603f61d0780904600331c9ef919f3d96b6
parent3ac87bbcda6167cf015c8ecdb8a7b70f03e1c96e (diff)
event/Loop: round epoll_wait() timeout up
This implements proper rounding, amending commit dcbb9fe07ce
-rw-r--r--src/event/Loop.cxx15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/event/Loop.cxx b/src/event/Loop.cxx
index a5475c3fb..6631c41c7 100644
--- a/src/event/Loop.cxx
+++ b/src/event/Loop.cxx
@@ -162,6 +162,18 @@ EventLoop::HandleTimers() noexcept
return Event::Duration(-1);
}
+template<class ToDuration, class Rep, class Period>
+static constexpr ToDuration
+duration_cast_round_up(std::chrono::duration<Rep, Period> d) noexcept
+{
+ using FromDuration = decltype(d);
+ constexpr auto one = std::chrono::duration_cast<FromDuration>(ToDuration(1));
+ constexpr auto round_add = one > one.zero()
+ ? one - FromDuration(1)
+ : one.zero();
+ return std::chrono::duration_cast<ToDuration>(d + round_add);
+}
+
/**
* Convert the given timeout specification to a milliseconds integer,
* to be used by functions like poll() and epoll_wait(). Any negative
@@ -171,8 +183,7 @@ static constexpr int
ExportTimeoutMS(Event::Duration timeout)
{
return timeout >= timeout.zero()
- /* round up (+1) to avoid unnecessary wakeups */
- ? int(std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count()) + 1
+ ? int(duration_cast_round_up<std::chrono::milliseconds>(timeout).count())
: -1;
}