From bca5559c6afaa1d3c3d53a5f27fc17ff430cf69e Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Fri, 27 Nov 2020 00:50:55 +0200 Subject: [PATCH] Race() call (#142) * Add `race` procedure call which extends `one` with FutureBase. * Fix race() and add test procedures. --- chronos/asyncfutures2.nim | 46 +++++++++ tests/testfut.nim | 197 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 243 insertions(+) diff --git a/chronos/asyncfutures2.nim b/chronos/asyncfutures2.nim index 231d4973..56613a65 100644 --- a/chronos/asyncfutures2.nim +++ b/chronos/asyncfutures2.nim @@ -932,3 +932,49 @@ proc one*[T](futs: varargs[Future[T]]): Future[Future[T]] = retFuture.cancelCallback = cancellation return retFuture + +proc race*(futs: varargs[FutureBase]): Future[FutureBase] = + ## Returns a future which will complete and return completed FutureBase, + ## when one of the futures in ``futs`` will be completed, failed or canceled. + ## + ## If the argument is empty, the returned future FAILS immediately. + ## + ## On success returned Future will hold finished FutureBase. + ## + ## On cancel futures in ``futs`` WILL NOT BE cancelled. + var retFuture = newFuture[FutureBase]("chronos.race()") + + # Because we can't capture varargs[T] in closures we need to create copy. + var nfuts = @futs + + proc cb(udata: pointer) {.gcsafe.} = + if not(retFuture.finished()): + var res: FutureBase + var rfut = cast[FutureBase](udata) + for i in 0..