tur/future
Future<T> and Promise<T> for asynchronous results.
A Promise is written once by the producer; the Future is read by the consumer.
Since: Phase T20-C
Promise
(defopaque Promise :ptr<void> :linear)
Future
(defopaque Future :ptr<void> :affine)
future-cell-new
(future-cell-new :Promise)
allocate and initialise a shared FutureCell (mutex, condvar, unset).
A Promise (write-end view of the new FutureCell); free with future-cell-free.
Since: Phase T20-C
future-cell-free
(future-cell-free [cell :Promise] :nil)
destroy the mutex/condvar and free a FutureCell.
| cell | FutureCell pointer from future-cell-new |
Since: Phase T20-C
promise-new
(promise-new :Promise)
allocate a new unsettled Promise/Future shared cell.
A Promise (write end); derive the read-end Future with future-of-cell.
(def p (promise-new)) (promise-fulfill p 42)
Since: Phase T20-C
promise-of-cell
(promise-of-cell [cell :Promise] :Promise)
return the Promise handle for a FutureCell (identity; for API symmetry).
| cell | FutureCell pointer from promise-new |
Since: Phase T20-C
future-of-cell
(future-of-cell [cell :Promise] :Future)
return the Future handle for a FutureCell (identity; for API symmetry).
| cell | FutureCell pointer from promise-new |
Since: Phase T20-C
future-handle
(future-handle [^borrow p :Promise] :Future)
borrow a Promise and derive a Future over the same cell.
Unlike future-of-cell (which *transfers* ownership, consuming the Promise), future-handle borrows the Promise (^borrow) and bumps the shared cell's reference count, so the producer keeps the Promise to settle while the consumer holds the returned Future to read and free. The cell is torn down only when both references are dropped (by promise-fulfill/-fail/-free on the Promise side and future-free on the Future side).
| p | Promise from promise-new (borrowed, not consumed) |
A Future over the same cell; free exactly once with future-free.
(let [p (promise-new)]
(let [f (future-handle p)]
(promise-fulfill p 42) ; consumes p, settles
(future-get f) ; read via f
(future-free f))) ; consumes f, frees the cell
Since: stdlib-linearity-affinity (Future aliasing fix)
promise-pair
(promise-pair [cell])
expand to a (Promise Future) pair list from a single shared cell.
| cell | FutureCell pointer from promise-new |
Since: Phase T20-C
promise-fulfill
(promise-fulfill [p :Promise v :int] :nil)
settle a promise with a successful value; wakes all future waiters.
| p | Promise (FutureCell) pointer | |
| v | fulfillment value |
Since: Phase T20-C
promise-fail
(promise-fail [p :Promise e :int] :nil)
settle a promise with an error code; wakes all future waiters.
| p | Promise (FutureCell) pointer | |
| e | error/exception code |
Since: Phase T20-C
promise-free
(promise-free [p :Promise] :nil)
free a promise and its shared FutureCell.
| p | Promise pointer from promise-new |
Since: Phase T20-C
future-done?
(future-done? [^borrow f :Future] :bool)
non-blocking check: return true if the future has been settled.
| f | Future (FutureCell) pointer |
true if settled (fulfilled or failed), false otherwise.
Since: Phase T20-C
future-get
(future-get [^borrow f :Future] :ptr<void>)
block until the future is settled; return a heap-allocated Result struct.
| f | Future (FutureCell) pointer |
A :ptr<void> to a Result in the canonical tagged layout (tag 0 = Ok).
(def result (future-get f))
Since: Phase T20-C
future-free
(future-free [f :Future] :nil)
free a future and its shared FutureCell.
| f | Future pointer from promise-new / future-of-cell |
Since: Phase T20-C
future-of
(future-of [v :int] :Future)
create a pre-fulfilled future holding value v.
| v | value the future should carry |
A Future already settled as ok with value v.
(def f (future-of 42)) ; immediately done
Since: Phase T20-C
future-error-of
(future-error-of [e :int] :Future)
create a pre-rejected future with error code e.
| e | error/exception code |
A Future already settled as failed with exn = e.
Since: Phase T20-C
future-cancel
(future-cancel [^borrow f :Future] :nil)
cancel a future if not yet settled; sets error code -2 (TUR_FUTURE_CANCELLED).
| f | Future (FutureCell) pointer |
Since: Phase T20-C
future-cancelled?
(future-cancelled? [^borrow f :Future] :bool)
return true if the future was cancelled (exn == -2).
| f | Future (FutureCell) pointer |
true if the future was settled via future-cancel, false otherwise.
Since: Phase T20-C
future-map
(future-map [^borrow f :Future ^fat fn :(fn [int] int)] :Future)
map fn over a fulfilled future value; propagate rejection unchanged.
| f | source Future pointer | |
| fn | a (fn [int] int) closure applied to the fulfilled value |
A new pre-settled Future with fn(value) on success, or the original error on failure.
Since: Phase T20-C
future-then
(future-then [^borrow f :Future ^fat fn :(fn [int] Future)] :Future)
flat-map fn over a future; fn must return a new Future ptr<void>.
| f | source Future pointer | |
| fn | a (fn [int] Future) closure producing the next Future |
The Future returned by fn, or a pre-rejected Future if f was rejected.
Since: Phase T20-C
future-race
(future-race [^borrow fa :Future ^borrow fb :Future] :Future)
race two futures; return a new future settled by whichever finishes first.
| fa | first Future pointer | |
| fb | second Future pointer |
A new pre-settled Future carrying the winner's value or error.
Since: Phase T20-C
future-all2
(future-all2 [^borrow fa :Future ^borrow fb :Future] :Future)
await both futures; settle ok with fa's value only if both succeed.
| fa | first Future pointer | |
| fb | second Future pointer |
A new pre-settled Future: ok with fa's value if both ok, else the first error.
Since: Phase T20-C
future-any2
(future-any2 [^borrow fa :Future ^borrow fb :Future] :Future)
return a future settled by the first fulfilled future; both rejecting yields fb's error.
| fa | first Future pointer | |
| fb | second Future pointer |
A new pre-settled Future with fa's value if fa ok, else fb's outcome.
Since: Phase T20-C
future-join
(future-join [^borrow fa :Future ^borrow fb :Future] :Future)
await both futures and produce a new future holding a Tuple2 of their values.
| fa | first Future pointer | |
| fb | second Future pointer |
A new pre-settled Future whose ok value is a pointer to Tuple2 { e1, e2 }; rejected with the first error if either future fails.
Since: Phase T20-C
tuple-first
(tuple-first [tup :ptr<void>] :int)
read the first element of a Tuple2 returned by future-join.
| tup | Tuple2 pointer from the ok value of a future-join result |
The int64 first element.
Since: Phase T20-C
tuple-second
(tuple-second [tup :ptr<void>] :int)
read the second element of a Tuple2 returned by future-join.
| tup | Tuple2 pointer from the ok value of a future-join result |
The int64 second element.
Since: Phase T20-C
tuple-free
(tuple-free [tup :ptr<void>] :nil)
free a Tuple2 allocated by future-join.
| tup | Tuple2 pointer to free |
Since: Phase T20-C
promise-new-pair
(promise-new-pair :Promise)
allocate a new unsettled Promise/Future shared cell (alias for promise-new).
Since: Phase T20-C
future-race-n
(future-race-n [futures :ptr<void> n :int] :Future)
race an array of n futures; return a new future settled by the first to finish.
| futures | pointer to an array of FutureCell* (ptr<void>[n]) | |
| n | number of futures in the array |
A new pre-settled Future with the first settled future's outcome.
Since: Phase T20-C
future-all-n
(future-all-n [futures :ptr<void> n :int] :Future)
await all n futures; settle ok (value 0) only if every future succeeds.
| futures | pointer to an array of FutureCell* (ptr<void>[n]) | |
| n | number of futures in the array |
A new pre-settled Future: ok with value 0 if all ok, else the first encountered error.
Since: Phase T20-C
future-any-n
(future-any-n [futures :ptr<void> n :int] :Future)
return a future settled by the first successfully fulfilled future in the array.
| futures | pointer to an array of FutureCell* (ptr<void>[n]) | |
| n | number of futures in the array |
A new pre-settled Future: ok with the first fulfilled value, or failed if all reject.
Since: Phase T20-C
future-timeout-thread
(future-timeout-thread [raw :ptr<void>] :ptr<void>)
pthread body for future-timeout. INTERNAL.
future-with-timeout-tfn
(future-with-timeout-tfn [raw :ptr<void>] :ptr<void>)
pthread body for the timeout half of future-with-timeout. INTERNAL.
future-with-timeout-wfn
(future-with-timeout-wfn [raw :ptr<void>] :ptr<void>)
pthread body for the wait half of future-with-timeout. INTERNAL.
future-timeout
(future-timeout [ms :int] :Future)
create a future that settles with error -1 after ms milliseconds.
| ms | timeout duration in milliseconds |
A Future that will be settled (is_ok = false, exn = -1) after ms ms.
(def t (future-timeout 5000)) ; rejects after 5 seconds
Since: Phase T20-C
future-with-timeout
(future-with-timeout [^borrow f :Future ms :int] :Future)
race a future against a timeout of ms milliseconds.
| f | source Future pointer | |
| ms | timeout in milliseconds; on expiry the result is rejected with exn = -1 |
A new Future settled with f's outcome if f finishes first, otherwise rejected with -1.
Since: Phase T20-C