Use monotonic clock for timeout

This commit is contained in:
Hiroki Noda 2018-12-24 06:22:53 +09:00
parent 0d3338a16b
commit a408aac808
3 changed files with 18 additions and 18 deletions

View file

@ -19,6 +19,7 @@ import core.stdc.stdio;
import core.sys.posix.unistd; import core.sys.posix.unistd;
import core.sys.posix.fcntl; import core.sys.posix.fcntl;
import core.sys.posix.sys.stat; import core.sys.posix.sys.stat;
import core.time;
import std.conv : octal; import std.conv : octal;
import std.datetime; import std.datetime;
import std.exception; import std.exception;
@ -652,11 +653,11 @@ struct DirectoryWatcher { // TODO: avoid all those heap allocations!
while (!m_context.changes.data.length) while (!m_context.changes.data.length)
m_context.changeEvent.wait(Duration.max, m_context.changeEvent.emitCount); m_context.changeEvent.wait(Duration.max, m_context.changeEvent.emitCount);
} else { } else {
SysTime now = Clock.currTime(UTC()); MonoTime now = MonoTime.currTime();
SysTime final_time = now + timeout; MonoTime final_time = now + timeout;
while (!m_context.changes.data.length) { while (!m_context.changes.data.length) {
m_context.changeEvent.wait(final_time - now, m_context.changeEvent.emitCount); m_context.changeEvent.wait(final_time - now, m_context.changeEvent.emitCount);
now = Clock.currTime(UTC()); now = MonoTime.currTime();
if (now >= final_time) break; if (now >= final_time) break;
} }
if (!m_context.changes.data.length) return false; if (!m_context.changes.data.length) return false;

View file

@ -767,20 +767,20 @@ struct LocalManualEvent {
private int doWait(bool interruptible)(Duration timeout, int emit_count) private int doWait(bool interruptible)(Duration timeout, int emit_count)
{ {
import std.datetime : Clock, SysTime, UTC; import core.time : MonoTime;
assert(m_waiter !is null, "LocalManualEvent is not initialized - use createManualEvent()"); assert(m_waiter !is null, "LocalManualEvent is not initialized - use createManualEvent()");
SysTime target_timeout, now; MonoTime target_timeout, now;
if (timeout != Duration.max) { if (timeout != Duration.max) {
try now = Clock.currTime(UTC()); try now = MonoTime.currTime();
catch (Exception e) { assert(false, e.msg); } catch (Exception e) { assert(false, e.msg); }
target_timeout = now + timeout; target_timeout = now + timeout;
} }
while (m_waiter.m_emitCount - emit_count <= 0) { while (m_waiter.m_emitCount - emit_count <= 0) {
m_waiter.wait!interruptible(timeout != Duration.max ? target_timeout - now : Duration.max); m_waiter.wait!interruptible(timeout != Duration.max ? target_timeout - now : Duration.max);
try now = Clock.currTime(UTC()); try now = MonoTime.currTime();
catch (Exception e) { assert(false, e.msg); } catch (Exception e) { assert(false, e.msg); }
if (now >= target_timeout) break; if (now >= target_timeout) break;
} }
@ -1008,7 +1008,7 @@ struct ManualEvent {
private int doWaitShared(bool interruptible)(Duration timeout, int emit_count) private int doWaitShared(bool interruptible)(Duration timeout, int emit_count)
shared { shared {
import std.datetime : SysTime, Clock, UTC; import core.time : MonoTime;
() @trusted { logTrace("wait shared %s", cast(void*)&this); } (); () @trusted { logTrace("wait shared %s", cast(void*)&this); } ();
@ -1017,9 +1017,9 @@ struct ManualEvent {
assert(ms_threadEvent != EventID.invalid, "Failed to create event!"); assert(ms_threadEvent != EventID.invalid, "Failed to create event!");
} }
SysTime target_timeout, now; MonoTime target_timeout, now;
if (timeout != Duration.max) { if (timeout != Duration.max) {
try now = Clock.currTime(UTC()); try now = MonoTime.currTime();
catch (Exception e) { assert(false, e.msg); } catch (Exception e) { assert(false, e.msg); }
target_timeout = now + timeout; target_timeout = now + timeout;
} }
@ -1032,7 +1032,7 @@ struct ManualEvent {
ec = this.emitCount; ec = this.emitCount;
if (timeout != Duration.max) { if (timeout != Duration.max) {
try now = Clock.currTime(UTC()); try now = MonoTime.currTime();
catch (Exception e) { assert(false, e.msg); } catch (Exception e) { assert(false, e.msg); }
if (now >= target_timeout) break; if (now >= target_timeout) break;
} }
@ -1296,7 +1296,7 @@ private final class ThreadLocalWaiter(bool EVENT_TRIGGERED) {
bool wait(bool interruptible)(Duration timeout, EventID evt = EventID.invalid, scope bool delegate() @safe nothrow exit_condition = null) bool wait(bool interruptible)(Duration timeout, EventID evt = EventID.invalid, scope bool delegate() @safe nothrow exit_condition = null)
@safe { @safe {
import std.datetime : SysTime, Clock, UTC; import core.time : MonoTime;
import vibe.internal.async : Waitable, asyncAwaitAny; import vibe.internal.async : Waitable, asyncAwaitAny;
TaskWaiter waiter_store; TaskWaiter waiter_store;
@ -1310,9 +1310,9 @@ private final class ThreadLocalWaiter(bool EVENT_TRIGGERED) {
assert(!waiter.next); assert(!waiter.next);
} }
SysTime target_timeout, now; MonoTime target_timeout, now;
if (timeout != Duration.max) { if (timeout != Duration.max) {
try now = Clock.currTime(UTC()); try now = MonoTime.currTime();
catch (Exception e) { assert(false, e.msg); } catch (Exception e) { assert(false, e.msg); }
target_timeout = now + timeout; target_timeout = now + timeout;
} }

View file

@ -8,8 +8,7 @@ module test;
import vibe.core.core; import vibe.core.core;
import vibe.core.log : logInfo; import vibe.core.log : logInfo;
import vibe.core.net; import vibe.core.net;
import core.time : msecs; import core.time : MonoTime, msecs;
import std.datetime : Clock, UTC;
void main() void main()
{ {
@ -21,12 +20,12 @@ void main()
}); });
runTask({ runTask({
auto start = Clock.currTime(UTC()); auto start = MonoTime.currTime();
try { try {
udp.recv(100.msecs); udp.recv(100.msecs);
assert(false, "Timeout did not occur."); assert(false, "Timeout did not occur.");
} catch (Exception e) { } catch (Exception e) {
auto duration = Clock.currTime(UTC()) - start; auto duration = MonoTime.currTime() - start;
assert(duration >= 99.msecs, "Timeout occurred too early"); assert(duration >= 99.msecs, "Timeout occurred too early");
assert(duration >= 99.msecs && duration < 150.msecs, "Timeout occurred too late."); assert(duration >= 99.msecs && duration < 150.msecs, "Timeout occurred too late.");
logInfo("UDP receive timeout test was successful."); logInfo("UDP receive timeout test was successful.");