diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 7c1b701b81..f4dc3de392 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -210,7 +210,12 @@ proc processPendingCallbacks(p: PDispatcherBase; didSomeWork: var bool) = cb() didSomeWork = true -proc adjustTimeout(pollTimeout: int, nextTimer: Option[int]): int {.inline.} = +proc adjustTimeout( + p: PDispatcherBase, pollTimeout: int, nextTimer: Option[int] +): int {.inline.} = + if p.callbacks.len != 0: + return 0 + if nextTimer.isNone() or pollTimeout == -1: return pollTimeout @@ -324,7 +329,7 @@ when defined(windows) or defined(nimdoc): result = false let nextTimer = processTimers(p, result) - let at = adjustTimeout(timeout, nextTimer) + let at = adjustTimeout(p, timeout, nextTimer) var llTimeout = if at == -1: winlean.INFINITE else: at.int32 @@ -1284,7 +1289,8 @@ else: result = false var keys: array[64, ReadyKey] let nextTimer = processTimers(p, result) - var count = p.selector.selectInto(adjustTimeout(timeout, nextTimer), keys) + var count = + p.selector.selectInto(adjustTimeout(p, timeout, nextTimer), keys) for i in 0.. target - 1000, "Took too short, should've taken " & + $target & "ms, but took " & $(timeTook*1000) & "ms") + assert(timeTook*1000 < target + 1000, "Took too long, should've taken " & + $target & "ms, but took " & $(timeTook*1000) & "ms") + +var + start: float + fut: Future[void] + +# NOTE: this uses poll(3000) to limit timing error potential. +start = epochTime() +fut = sleepAsync(50) and sleepAsync(150) and doubleSleep(40) +while not fut.finished: + poll(3000) +assertTime(150, epochTime() - start) + +start = epochTime() +fut = sleepAsync(50) and sleepAsync(150) and doubleSleep(100) +while not fut.finished: + poll(3000) +assertTime(200, epochTime() - start) + +start = epochTime() +fut = sleepAsync(50) and sleepAsync(150) and doubleSleep(40) and sleepAsync(300) +while not fut.finished: + poll(3000) +assertTime(300, epochTime() - start) + +start = epochTime() +fut = sleepAsync(50) and sleepAsync(150) and doubleSleep(100) and sleepAsync(300) +while not fut.finished: + poll(3000) +assertTime(300, epochTime() - start) + +start = epochTime() +fut = (sleepAsync(50) and sleepAsync(150) and doubleSleep(40)) or sleepAsync(700) +while not fut.finished: + poll(3000) +assertTime(150, epochTime() - start) + +start = epochTime() +fut = (sleepAsync(50) and sleepAsync(150) and doubleSleep(100)) or sleepAsync(700) +while not fut.finished: + poll(3000) +assertTime(200, epochTime() - start)