Skip to content

Commit cc96f1a

Browse files
committed
fix: don't sleep/block if ticks are outstanding
1 parent 31ddf9b commit cc96f1a

2 files changed

Lines changed: 37 additions & 3 deletions

File tree

chronos/internal/asyncengine.nim

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,15 @@ template processTimersGetTimeout(loop, timeout: untyped) =
113113
timeout = (lastFinish - curTime).getAsyncTimestamp()
114114

115115
if timeout == 0:
116-
if (len(loop.callbacks) == 0) and (len(loop.idlers) == 0):
116+
if (len(loop.callbacks) == 0) and (len(loop.idlers) == 0) and
117+
(len(loop.ticks) == 0):
117118
when defined(windows):
118119
timeout = INFINITE
119120
else:
120121
timeout = -1
121122
else:
122-
if (len(loop.callbacks) != 0) or (len(loop.idlers) != 0):
123+
if (len(loop.callbacks) != 0) or (len(loop.idlers) != 0) or
124+
(len(loop.ticks) != 0):
123125
timeout = 0
124126

125127
template processTimers(loop: untyped) =

tests/testtime.nim

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
# MIT license (LICENSE-MIT)
88
import std/os
99
import unittest2
10-
import ../chronos, ../chronos/timer
10+
import ../chronos/internal/[asyncengine, asyncfutures]
11+
import ../chronos/timer
1112

1213
{.used.}
1314

@@ -127,3 +128,34 @@ suite "Asynchronous timers & steps test suite":
127128

128129
check:
129130
fut3.completed() == true
131+
132+
test "Cancellation retry tick does not wait for next timer":
133+
const NextTimerSleep = 50.milliseconds
134+
135+
let gate = newFuture[void]("cancelAndWait.gate")
136+
var
137+
slept = false
138+
workerFut: Future[void]
139+
140+
proc cancelWorker(): Future[void] {.async.} =
141+
await gate
142+
await workerFut.cancelAndWait()
143+
144+
proc worker() {.async.} =
145+
try:
146+
await gate
147+
await sleepAsync(NextTimerSleep)
148+
slept = true
149+
except CancelledError:
150+
discard
151+
152+
let cancelFut = cancelWorker()
153+
workerFut = worker()
154+
gate.complete()
155+
156+
while not cancelFut.finished:
157+
poll()
158+
159+
check:
160+
workerFut.finished
161+
not slept

0 commit comments

Comments
 (0)