Add allFinished() primitive. (#87)
* Add allCompleted() primitive. * Rename it to allFinished(). * Fix allFinished Future's static name. Use `mitems()` instead of `for`.
This commit is contained in:
parent
72b4f14427
commit
cbd8e03823
|
@ -701,6 +701,43 @@ proc allFutures*[T](futs: varargs[Future[T]]): Future[void] =
|
|||
|
||||
return retFuture
|
||||
|
||||
proc allFinished*[T](futs: varargs[Future[T]]): Future[seq[Future[T]]] =
|
||||
## Returns a future which will complete only when all futures in ``futs``
|
||||
## will be completed, failed or canceled.
|
||||
##
|
||||
## Returned sequence will hold all the Future[T] objects passed to
|
||||
## ``allCompleted`` with the order preserved.
|
||||
##
|
||||
## If the argument is empty, the returned future COMPLETES immediately.
|
||||
##
|
||||
## On cancel all the awaited futures ``futs`` WILL NOT BE cancelled.
|
||||
var retFuture = newFuture[seq[Future[T]]]("chronos.allFinished()")
|
||||
let totalFutures = len(futs)
|
||||
var completedFutures = 0
|
||||
|
||||
var nfuts = @futs
|
||||
|
||||
proc cb(udata: pointer) {.gcsafe.} =
|
||||
if not(retFuture.finished()):
|
||||
inc(completedFutures)
|
||||
if completedFutures == totalFutures:
|
||||
retFuture.complete(nfuts)
|
||||
|
||||
proc cancellation(udata: pointer) {.gcsafe.} =
|
||||
# On cancel we remove all our callbacks only.
|
||||
for fut in nfuts.mitems():
|
||||
if not(fut.finished()):
|
||||
fut.removeCallback(cb)
|
||||
|
||||
for fut in nfuts:
|
||||
fut.addCallback(cb)
|
||||
|
||||
retFuture.cancelCallback = cancellation
|
||||
if len(nfuts) == 0:
|
||||
retFuture.complete(nfuts)
|
||||
|
||||
return retFuture
|
||||
|
||||
proc one*[T](futs: varargs[Future[T]]): Future[Future[T]] =
|
||||
## Returns a future which will complete and return completed Future[T] inside,
|
||||
## when one of the futures in ``futs`` will be completed, failed or canceled.
|
||||
|
|
Loading…
Reference in New Issue