aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/future.ml
diff options
context:
space:
mode:
authorGravatar Enrico Tassi <Enrico.Tassi@inria.fr>2014-11-28 15:59:51 +0100
committerGravatar Enrico Tassi <Enrico.Tassi@inria.fr>2014-11-28 15:59:51 +0100
commit9f4546a103607e0f2283897c094ce05ffa2d5c21 (patch)
treee3d97e8220114837302f902d79ce66dddb810127 /lib/future.ml
parenta9fd21ac2b2e3908d8eb8d5a549c43949cddc69a (diff)
Future: API for blocking futures
Diffstat (limited to 'lib/future.ml')
-rw-r--r--lib/future.ml34
1 files changed, 19 insertions, 15 deletions
diff --git a/lib/future.ml b/lib/future.ml
index 4437cec84..b851f912c 100644
--- a/lib/future.ml
+++ b/lib/future.ml
@@ -48,9 +48,7 @@ type 'a assignement = [ `Val of 'a | `Exn of exn | `Comp of 'a computation]
(* Val is not necessarily a final state, so the
computation restarts from the state stocked into Val *)
and 'a comp =
- | Delegated of (unit -> 'a assignement)
- (* TODO in some cases one would like to block, sock here
- a mutex and a condition to make this possible *)
+ | Delegated of (unit -> unit)
| Closure of (unit -> 'a)
| Val of 'a * Dyn.t option
| Exn of exn (* Invariant: this exception is always "fixed" as in fix_exn *)
@@ -95,17 +93,23 @@ let from_here ?(fix_exn=id) v = create fix_exn (Val (v, Some (!freeze ())))
let fix_exn_of ck = let _, fix_exn, _ = get ck in fix_exn
-let default_force () = raise NotReady
-let assignement ck = fun v ->
- let _, fix_exn, c = get ck in
- assert (match !c with Delegated _ -> true | _ -> false);
- match v with
- | `Val v -> c := Val (v, None)
- | `Exn e -> c := Exn (fix_exn e)
- | `Comp f -> let _, _, comp = get f in c := !comp
-let create_delegate ?(force=default_force) fix_exn =
- let ck = create fix_exn (Delegated force) in
- ck, assignement ck
+let create_delegate ?(blocking=false) fix_exn =
+ let assignement signal ck = fun v ->
+ let _, fix_exn, c = get ck in
+ assert (match !c with Delegated _ -> true | _ -> false);
+ begin match v with
+ | `Val v -> c := Val (v, None)
+ | `Exn e -> c := Exn (fix_exn e)
+ | `Comp f -> let _, _, comp = get f in c := !comp end;
+ signal () in
+ let wait, signal =
+ if not blocking then (fun () -> raise NotReady), ignore else
+ let lock = Mutex.create () in
+ let cond = Condition.create () in
+ (fun () -> Mutex.lock lock; Condition.wait cond lock; Mutex.unlock lock),
+ (fun () -> Mutex.lock lock; Condition.broadcast cond; Mutex.unlock lock) in
+ let ck = create fix_exn (Delegated wait) in
+ ck, assignement signal ck
(* TODO: get rid of try/catch to be stackless *)
let rec compute ~pure ck : 'a value =
@@ -113,7 +117,7 @@ let rec compute ~pure ck : 'a value =
match !c with
| Val (x, _) -> `Val x
| Exn e -> `Exn e
- | Delegated f -> assignement ck (f ()); compute ~pure ck
+ | Delegated wait -> wait (); compute ~pure ck
| Closure f ->
try
let data = f () in