From 8e71949b785ca2b2bc61d0f95c5ac88fa87621fe Mon Sep 17 00:00:00 2001 From: Anatoly Galiulin Date: Thu, 29 Dec 2016 11:22:50 +0700 Subject: [PATCH] Add pending operations presence check function, fixes #5155 --- lib/pure/asyncdispatch.nim | 15 ++++++++++++++- lib/upcoming/asyncdispatch.nim | 12 +++++++++++- tests/async/tpendingcheck.nim | 21 +++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 tests/async/tpendingcheck.nim diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 1367bc411f..b72596060d 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -254,8 +254,14 @@ when defined(windows) or defined(nimdoc): "Operation performed on a socket which has not been registered with" & " the dispatcher yet.") + proc hasPendingOperations*(): bool = + ## Returns `true` if the global dispatcher has pending operations. + let p = getGlobalDispatcher() + p.handles.len != 0 or p.timers.len != 0 or p.callbacks.len != 0 + proc poll*(timeout = 500) = - ## Waits for completion events and processes them. + ## Waits for completion events and processes them. Raises ``ValueError`` + ## if there are no pending operations. let p = getGlobalDispatcher() if p.handles.len == 0 and p.timers.len == 0 and p.callbacks.len == 0: raise newException(ValueError, @@ -1056,8 +1062,15 @@ else: newCBs.add(cb) callbacks = newCBs & callbacks + proc hasPendingOperations*(): bool = + let p = getGlobalDispatcher() + p.selector.len != 0 or p.timers.len != 0 or p.callbacks.len != 0 + proc poll*(timeout = 500) = let p = getGlobalDispatcher() + if p.selector.len == 0 and p.timers.len == 0 and p.callbacks.len == 0: + raise newException(ValueError, + "No handles or timers registered in dispatcher.") if p.selector.len > 0: for info in p.selector.select(p.adjustedTimeout(timeout)): diff --git a/lib/upcoming/asyncdispatch.nim b/lib/upcoming/asyncdispatch.nim index ca5c1f64c3..78c7afffcd 100644 --- a/lib/upcoming/asyncdispatch.nim +++ b/lib/upcoming/asyncdispatch.nim @@ -231,8 +231,14 @@ when defined(windows) or defined(nimdoc): "Operation performed on a socket which has not been registered with" & " the dispatcher yet.") + proc hasPendingOperations*(): bool = + ## Returns `true` if the global dispatcher has pending operations. + let p = getGlobalDispatcher() + p.handles.len != 0 or p.timers.len != 0 or p.callbacks.len != 0 + proc poll*(timeout = 500) = - ## Waits for completion events and processes them. + ## Waits for completion events and processes them. Raises ``ValueError`` + ## if there are no pending operations. let p = getGlobalDispatcher() if p.handles.len == 0 and p.timers.len == 0 and p.callbacks.len == 0: raise newException(ValueError, @@ -1182,6 +1188,10 @@ else: raise newException(ValueError, "File descriptor not registered.") p.selector.updateHandle(fd.SocketHandle, newEvents) + proc hasPendingOperations*(): bool = + let p = getGlobalDispatcher() + not p.selector.isEmpty() or p.timers.len != 0 or p.callbacks.len != 0 + proc poll*(timeout = 500) = var keys: array[64, ReadyKey[AsyncData]] diff --git a/tests/async/tpendingcheck.nim b/tests/async/tpendingcheck.nim new file mode 100644 index 0000000000..825acb6135 --- /dev/null +++ b/tests/async/tpendingcheck.nim @@ -0,0 +1,21 @@ +discard """ + file: "tpendingcheck.nim" + exitcode: 0 + output: "" +""" + +import asyncdispatch + +doAssert(not hasPendingOperations()) + +proc test() {.async.} = + await sleepAsync(100) + +var f = test() +while not f.finished: + doAssert(hasPendingOperations()) + poll(10) +f.read + +doAssert(not hasPendingOperations()) +