mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
changed the implementation of Behavior.Fut
This commit is contained in:
parent
59fb4a0d47
commit
fa40412216
1 changed files with 25 additions and 30 deletions
55
behavior.ml
55
behavior.ml
|
|
@ -108,39 +108,34 @@ let closure f =
|
||||||
(** {2 Lightweight futures} *)
|
(** {2 Lightweight futures} *)
|
||||||
|
|
||||||
module Fut = struct
|
module Fut = struct
|
||||||
type 'a t = {
|
type 'a t = 'a fut_cell ref
|
||||||
mutable value : 'a option;
|
and 'a fut_cell =
|
||||||
mutable handlers : ('a -> unit) list;
|
| Waiting of ('a -> unit) list
|
||||||
}
|
| Done of 'a
|
||||||
|
|
||||||
let create () =
|
let create () =
|
||||||
let fut = {
|
let fut = ref (Waiting []) in
|
||||||
value = None;
|
let send x = match !fut with
|
||||||
handlers = [];
|
| Done _ -> raise (Invalid_argument "Behavior.Fut.create: future already set")
|
||||||
} in
|
| Waiting handlers ->
|
||||||
let send x = match fut.value with
|
List.iter (fun f -> f x) handlers;
|
||||||
| Some _ -> raise (Invalid_argument "Behavior.Fut.create: future already set")
|
fut := Done x
|
||||||
| None ->
|
|
||||||
fut.value <- Some x;
|
|
||||||
List.iter (fun f -> f x) fut.handlers
|
|
||||||
in
|
in
|
||||||
fut, send
|
fut, send
|
||||||
|
|
||||||
(* add [h] as a handler that waits for [fut] to complete. May call [h]
|
(* add [h] as a handler that waits for [fut] to complete. May call [h]
|
||||||
immediately *)
|
immediately *)
|
||||||
let subscribe fut h =
|
let subscribe fut h =
|
||||||
match fut.value with
|
match !fut with
|
||||||
| None -> fut.handlers <- h :: fut.handlers
|
| Done x -> h x
|
||||||
| Some x -> h x
|
| Waiting l -> fut := Waiting (h :: l)
|
||||||
|
|
||||||
let is_set fut = match fut.value with
|
let is_set fut = match !fut with
|
||||||
| None -> false
|
| Done _ -> true
|
||||||
| Some _ -> true
|
| Waiting _ -> false
|
||||||
|
|
||||||
let return x = {
|
let return x =
|
||||||
value = Some x;
|
ref (Done x)
|
||||||
handlers = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let bind fut f =
|
let bind fut f =
|
||||||
(* result *)
|
(* result *)
|
||||||
|
|
@ -155,7 +150,7 @@ module Fut = struct
|
||||||
let next e =
|
let next e =
|
||||||
let res, send = create () in
|
let res, send = create () in
|
||||||
let ev = React.E.map send (React.E.once e) in
|
let ev = React.E.map send (React.E.once e) in
|
||||||
res.handlers <- [fun _ -> ignore ev]; (* keep reference *)
|
subscribe res (fun _ -> ignore ev); (* keep reference *)
|
||||||
res
|
res
|
||||||
|
|
||||||
let wait fut =
|
let wait fut =
|
||||||
|
|
@ -175,9 +170,9 @@ module Fut = struct
|
||||||
let any_set = ref false in
|
let any_set = ref false in
|
||||||
(try
|
(try
|
||||||
List.iter
|
List.iter
|
||||||
(fun fut -> match fut.value with
|
(fun fut -> match !fut with
|
||||||
| None -> ()
|
| Waiting _ -> ()
|
||||||
| Some x -> any_set := true; send x; raise Exit)
|
| Done x -> any_set := true; send x; raise Exit)
|
||||||
l
|
l
|
||||||
with Exit -> ());
|
with Exit -> ());
|
||||||
(* if no element of [l] is already set, add handlers *)
|
(* if no element of [l] is already set, add handlers *)
|
||||||
|
|
@ -216,9 +211,9 @@ module Fut = struct
|
||||||
res
|
res
|
||||||
|
|
||||||
(** Get value, which must be present *)
|
(** Get value, which must be present *)
|
||||||
let unsafe_get fut = match fut.value with
|
let unsafe_get fut = match !fut with
|
||||||
| None -> assert false
|
| Waiting _-> assert false
|
||||||
| Some x -> x
|
| Done x -> x
|
||||||
|
|
||||||
let l2 f a b =
|
let l2 f a b =
|
||||||
let res, send = create () in
|
let res, send = create () in
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue