Fix wrong epoll timeout in case of already expired timers.

This could cause process/task starvation due to an infinite wait timeout.
This commit is contained in:
Sönke Ludwig 2016-12-29 22:51:07 +01:00
parent 671fd0f078
commit a3ca0965cf
2 changed files with 4 additions and 4 deletions

View file

@ -34,13 +34,13 @@ final class EpollEventLoop : PosixEventLoop {
override bool doProcessEvents(Duration timeout) override bool doProcessEvents(Duration timeout)
@trusted { @trusted {
import std.algorithm : min; import std.algorithm : min, max;
//assert(Fiber.getThis() is null, "processEvents may not be called from within a fiber!"); //assert(Fiber.getThis() is null, "processEvents may not be called from within a fiber!");
debug (EventCoreEpollDebug) print("Epoll wait %s, %s", m_events.length, timeout); debug (EventCoreEpollDebug) print("Epoll wait %s, %s", m_events.length, timeout);
long tomsec; long tomsec;
if (timeout == Duration.max) tomsec = long.max; if (timeout == Duration.max) tomsec = long.max;
else tomsec = (timeout.total!"hnsecs" + 9999) / 10_000; else tomsec = max((timeout.total!"hnsecs" + 9999) / 10_000, 0);
auto ret = epoll_wait(m_epoll, m_events.ptr, cast(int)m_events.length, tomsec > int.max ? -1 : cast(int)tomsec); auto ret = epoll_wait(m_epoll, m_events.ptr, cast(int)m_events.length, tomsec > int.max ? -1 : cast(int)tomsec);
debug (EventCoreEpollDebug) print("Epoll wait done: %s", ret); debug (EventCoreEpollDebug) print("Epoll wait done: %s", ret);

View file

@ -132,7 +132,7 @@ final class PosixEventDriverCore(Loop : PosixEventLoop, Timers : EventDriverTime
final override ExitReason processEvents(Duration timeout) final override ExitReason processEvents(Duration timeout)
{ {
import std.algorithm : min; import std.algorithm : min, max;
import core.time : hnsecs, seconds; import core.time : hnsecs, seconds;
if (m_exit) { if (m_exit) {
@ -150,7 +150,7 @@ final class PosixEventDriverCore(Loop : PosixEventLoop, Timers : EventDriverTime
} else { } else {
long now = currStdTime; long now = currStdTime;
do { do {
auto nextto = min(m_timers.getNextTimeout(now), timeout); auto nextto = max(min(m_timers.getNextTimeout(now), timeout), 0.seconds);
got_events = m_loop.doProcessEvents(nextto); got_events = m_loop.doProcessEvents(nextto);
long prev_step = now; long prev_step = now;
now = currStdTime; now = currStdTime;