Skip to content

Commit f134d9c

Browse files
committed
Switch to Eio: manual changes
1 parent 3c87616 commit f134d9c

17 files changed

+338
-342
lines changed

src/lib/eliom_bus.client.ml

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -34,37 +34,37 @@ type ('a, 'b) t =
3434
; mutable max_size : int
3535
; write : 'a list -> unit
3636
; mutable waiter : unit -> unit
37-
; mutable last_wait : unit Promise.t
37+
; mutable last_wait : Switch.t option
3838
; mutable original_stream_available : bool
39-
; error_h : 'b option Promise.t * exn Lwt.u }
39+
; error_h : 'b option Promise.or_exn * (exn, exn) result Promise.u }
4040

4141
(* clone streams such that each clone of the original stream raise the same exceptions *)
4242
let consume (t, u) s =
43-
let t' =
44-
try Eliom_stream.iter (fun _ -> ()) s
43+
let p, w = Promise.create () in
44+
Eliom_lib.fork (fun () ->
45+
try Promise.resolve_ok w (Eliom_stream.iter (fun _ -> ()) s)
4546
with e ->
46-
(match Promise.peek t with None -> Lwt.wakeup_exn u e | _ -> ());
47-
raise e
48-
in
49-
Fiber.any
50-
(List.map
51-
(fun p () -> Promise.await p)
52-
(* TODO: ciao-lwt: The list [[ Lwt.bind t (fun _ -> Lwt.return_unit); t' ]] is expected to be a list of promises. Use [Fiber.fork_promise] to make a promise. *)
53-
[ (let _ = t in
54-
())
55-
; t' ])
47+
(match Promise.peek t with None -> Promise.resolve_error u e | _ -> ());
48+
Promise.resolve_error w e);
49+
Eliom_lib.fork (fun () ->
50+
try Promise.resolve_ok w (ignore (Promise.await_exn t))
51+
with e -> Promise.resolve_error w e);
52+
Promise.await_exn p
5653

5754
let clone_exn (t, u) s =
5855
let s' = Eliom_stream.clone s in
5956
Eliom_stream.from (fun () ->
6057
try
61-
Fiber.any
62-
(List.map
63-
(fun p () -> Promise.await p)
64-
(* TODO: ciao-lwt: The list [[ Eliom_stream.get s'; t ]] is expected to be a list of promises. Use [Fiber.fork_promise] to make a promise. *)
65-
[Eliom_stream.get s'; t])
58+
let p, w = Promise.create () in
59+
Eliom_lib.fork (fun () ->
60+
try Promise.resolve_ok w (Eliom_stream.get s')
61+
with e -> Promise.resolve_error w e);
62+
Eliom_lib.fork (fun () ->
63+
try Promise.resolve_ok w (Promise.await_exn t)
64+
with e -> Promise.resolve_error w e);
65+
Promise.await_exn p
6666
with e ->
67-
(match Promise.peek t with None -> Lwt.wakeup_exn u e | _ -> ());
67+
(match Promise.peek t with None -> Promise.resolve_error u e | _ -> ());
6868
raise e)
6969

7070
type ('a, 'att, 'co, 'ext, 'reg) callable_bus_service =
@@ -93,15 +93,16 @@ let create service channel waiter =
9393
with Eliom_request.Failed_request 204 -> ()
9494
in
9595
let error_h =
96-
let t, u =
96+
let t, (u : (exn, exn) result Promise.u) =
9797
Promise.create
9898
(* TODO: ciao-lwt: Translation is incomplete, [Promise.await] must be called on the promise when it's part of control-flow. *)
9999
()
100100
in
101+
let tt, uu = Promise.create () in
101102
( (try
102-
let _ = t in
103+
ignore (Promise.await t);
103104
assert false
104-
with e -> raise e)
105+
with e -> Promise.resolve_error uu e; tt)
105106
, u )
106107
in
107108
let stream =
@@ -118,7 +119,7 @@ let create service channel waiter =
118119
; max_size = 20
119120
; write
120121
; waiter
121-
; last_wait = ()
122+
; last_wait = None
122123
; original_stream_available = true
123124
; error_h }
124125
in
@@ -152,32 +153,26 @@ let flush t =
152153
let l = List.rev (Queue.fold (fun l v -> v :: l) [] t.queue) in
153154
Queue.clear t.queue; t.write l
154155

156+
exception Cancelled
157+
155158
let try_flush t =
156-
Lwt.cancel
157-
(* TODO: ciao-lwt: Use [Switch] or [Cancel] for defining a cancellable context. *)
158-
(* TODO: ciao-lwt: Use [Switch] or [Cancel] for defining a cancellable context. *)
159-
t.last_wait;
159+
Option.iter (fun o -> Switch.fail o Cancelled) t.last_wait;
160160
if Queue.length t.queue >= t.max_size
161161
then flush t
162162
else
163-
let th =
164-
Lwt.protected
165-
(* TODO: ciao-lwt: Use [Switch] or [Cancel] for defining a cancellable context. *)
166-
(* TODO: ciao-lwt: Use [Switch] or [Cancel] for defining a cancellable context. *)
167-
(t.waiter ())
168-
in
169-
t.last_wait <- th;
170-
let _ = th; flush t in
171-
()
163+
Eliom_lib.fork (fun () ->
164+
Switch.run_protected (fun sw ->
165+
(*VVV ???*)
166+
t.last_wait <- Some sw;
167+
t.waiter ());
168+
flush t)
172169

173170
let write t v = Queue.add v t.queue; try_flush t
174171
let close {channel; _} = Eliom_comet.close channel
175172
let set_queue_size b s = b.max_size <- s
176173

177174
let set_time_before_flush b t =
178175
b.waiter <-
179-
(if t <= 0.
180-
then fun x1 -> Fiber.yield x1
181-
else fun () -> Js_of_ocaml_eio.Eio_js.sleep t)
176+
(if t <= 0. then Fiber.yield else fun () -> Js_of_ocaml_eio.Eio_js.sleep t)
182177

183178
let force_link = ()

src/lib/eliom_client.client.ml

Lines changed: 82 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,13 @@ let run_onunload_wrapper set_content cancel =
7676
run_callbacks (flush_onunload ());
7777
set_content ()
7878

79-
let lwt_onload () =
79+
let onload_promise () =
8080
let t, u =
8181
Promise.create
8282
(* TODO: ciao-lwt: Translation is incomplete, [Promise.await] must be called on the promise when it's part of control-flow. *)
8383
()
8484
in
85-
onload (fun x1 -> Promise.resolve u x1);
85+
onload (fun () -> Promise.resolve u ());
8686
t
8787

8888
(* == Initialize the client values sent with a request *)
@@ -432,11 +432,11 @@ let scroll_to_fragment ?offset fragment =
432432
let elem = Dom_html.document##(getElementById (Js.string fragment)) in
433433
Js.Opt.iter elem scroll_to_element)
434434

435-
let with_progress_cursor : 'a Promise.t -> 'a =
436-
fun t ->
435+
let with_progress_cursor : (unit -> 'a) -> 'a =
436+
fun f ->
437437
try
438438
Dom_html.document##.body##.style##.cursor := Js.string "progress";
439-
let res = t in
439+
let res = f () in
440440
Dom_html.document##.body##.style##.cursor := Js.string "auto";
441441
res
442442
with exn ->
@@ -698,7 +698,7 @@ let set_active_page p =
698698

699699
(* This key serves as a hook to access the page the currently running code is
700700
generating. *)
701-
let this_page : page Lwt.key = Fiber.create_key ()
701+
let this_page : page Fiber.key = Fiber.create_key ()
702702

703703
let get_this_page () =
704704
match Fiber.get this_page with
@@ -1442,23 +1442,24 @@ module Page_status = struct
14421442
stop_event ?stop @@ React.E.map action @@ maybe_just_once ~once
14431443
@@ Events.inactive ()
14441444

1445+
exception Cancelled
1446+
14451447
let while_active ?now ?(stop = React.E.never) action =
1446-
let thread = ref () in
1447-
onactive ?now ~stop (fun () -> thread := action ());
1448-
oninactive ~stop (fun () ->
1449-
Lwt.cancel
1450-
(* TODO: ciao-lwt: Use [Switch] or [Cancel] for defining a cancellable context. *)
1451-
(* TODO: ciao-lwt: Use [Switch] or [Cancel] for defining a cancellable context. *)
1452-
!thread);
1453-
Dom_reference.retain_generic (get_this_page ())
1454-
~keep:
1455-
(React.E.map
1456-
(fun () ->
1457-
Lwt.cancel
1458-
(* TODO: ciao-lwt: Use [Switch] or [Cancel] for defining a cancellable context. *)
1459-
(* TODO: ciao-lwt: Use [Switch] or [Cancel] for defining a cancellable context. *)
1460-
!thread)
1461-
stop)
1448+
let active_switch = ref None in
1449+
onactive ?now ~stop (fun () ->
1450+
Eio.Switch.run (fun sw ->
1451+
active_switch := Some sw;
1452+
Eio.Fiber.fork ~sw action);
1453+
oninactive ~stop (fun () ->
1454+
Option.iter (fun sw -> Eio.Switch.fail sw Cancelled) !active_switch);
1455+
Dom_reference.retain_generic (get_this_page ())
1456+
~keep:
1457+
(React.E.map
1458+
(fun () ->
1459+
Option.iter
1460+
(fun sw -> Eio.Switch.fail sw Cancelled)
1461+
!active_switch)
1462+
stop))
14621463
end
14631464

14641465
let is_in_cache state_id =
@@ -1905,8 +1906,8 @@ and change_page :
19051906
~service ?hostname ?port ?fragment ?keep_nl_params ~nl_params
19061907
?keep_get_na_params get_params post_params
19071908
else
1908-
with_progress_cursor
1909-
(match xhr with
1909+
with_progress_cursor (fun () ->
1910+
match xhr with
19101911
| Some (Some tmpl as t)
19111912
when t = Eliom_request_info.get_request_template () ->
19121913
Logs.debug ~src:section_page (fun fmt ->
@@ -2042,29 +2043,28 @@ and reload_without_na_params ~replace ~uri ~fallback =
20422043
(* Function used in "onclick" event handler of <a>. *)
20432044
let change_page_uri_a ?cookies_info ?tmpl ?(get_params = []) full_uri =
20442045
Logs.debug ~src:section_page (fun fmt -> fmt "Change page uri");
2045-
with_progress_cursor
2046-
(let uri, fragment = Url.split_fragment full_uri in
2047-
if uri <> get_current_uri () || fragment = None
2048-
then (
2049-
if is_client_app ()
2050-
then failwith "Change_page_uri_a called on client app";
2051-
match tmpl with
2052-
| Some t when tmpl = Eliom_request_info.get_request_template () ->
2053-
let uri, content =
2054-
Eliom_request.http_get ?cookies_info uri
2055-
((Eliom_request.nl_template_string, t) :: get_params)
2056-
Eliom_request.string_result
2057-
in
2058-
set_template_content ~replace:false ~uri ?fragment content
2059-
| _ ->
2060-
let uri, content =
2061-
Eliom_request.http_get ~expecting_process_page:true ?cookies_info
2062-
uri get_params Eliom_request.xml_result
2063-
in
2064-
set_content ~replace:false ~uri ?fragment content)
2065-
else (
2066-
change_url_string ~replace:true full_uri;
2067-
scroll_to_fragment fragment))
2046+
with_progress_cursor (fun () ->
2047+
let uri, fragment = Url.split_fragment full_uri in
2048+
if uri <> get_current_uri () || fragment = None
2049+
then (
2050+
if is_client_app () then failwith "Change_page_uri_a called on client app";
2051+
match tmpl with
2052+
| Some t when tmpl = Eliom_request_info.get_request_template () ->
2053+
let uri, content =
2054+
Eliom_request.http_get ?cookies_info uri
2055+
((Eliom_request.nl_template_string, t) :: get_params)
2056+
Eliom_request.string_result
2057+
in
2058+
set_template_content ~replace:false ~uri ?fragment content
2059+
| _ ->
2060+
let uri, content =
2061+
Eliom_request.http_get ~expecting_process_page:true ?cookies_info
2062+
uri get_params Eliom_request.xml_result
2063+
in
2064+
set_content ~replace:false ~uri ?fragment content)
2065+
else (
2066+
change_url_string ~replace:true full_uri;
2067+
scroll_to_fragment fragment))
20682068

20692069
let change_page_uri ?replace full_uri =
20702070
Logs.debug ~src:section_page (fun fmt -> fmt "Change page uri");
@@ -2088,42 +2088,42 @@ let change_page_uri ?replace full_uri =
20882088
(* Functions used in "onsubmit" event handler of <form>. *)
20892089

20902090
let change_page_get_form ?cookies_info ?tmpl form full_uri =
2091-
with_progress_cursor
2092-
(let form = Js.Unsafe.coerce form in
2093-
let uri, fragment = Url.split_fragment full_uri in
2094-
match tmpl with
2095-
| Some t when tmpl = Eliom_request_info.get_request_template () ->
2096-
let uri, content =
2097-
Eliom_request.send_get_form
2098-
~get_args:[Eliom_request.nl_template_string, t]
2099-
?cookies_info form uri Eliom_request.string_result
2100-
in
2101-
set_template_content ~replace:false ~uri ?fragment content
2102-
| _ ->
2103-
let uri, content =
2104-
Eliom_request.send_get_form ~expecting_process_page:true
2105-
?cookies_info form uri Eliom_request.xml_result
2106-
in
2107-
set_content ~replace:false ~uri ?fragment content)
2091+
with_progress_cursor (fun () ->
2092+
let form = Js.Unsafe.coerce form in
2093+
let uri, fragment = Url.split_fragment full_uri in
2094+
match tmpl with
2095+
| Some t when tmpl = Eliom_request_info.get_request_template () ->
2096+
let uri, content =
2097+
Eliom_request.send_get_form
2098+
~get_args:[Eliom_request.nl_template_string, t]
2099+
?cookies_info form uri Eliom_request.string_result
2100+
in
2101+
set_template_content ~replace:false ~uri ?fragment content
2102+
| _ ->
2103+
let uri, content =
2104+
Eliom_request.send_get_form ~expecting_process_page:true ?cookies_info
2105+
form uri Eliom_request.xml_result
2106+
in
2107+
set_content ~replace:false ~uri ?fragment content)
21082108

21092109
let change_page_post_form ?cookies_info ?tmpl form full_uri =
2110-
with_progress_cursor
2111-
(let form = Js.Unsafe.coerce form in
2112-
let uri, fragment = Url.split_fragment full_uri in
2113-
match tmpl with
2114-
| Some t when tmpl = Eliom_request_info.get_request_template () ->
2115-
let uri, content =
2116-
Eliom_request.send_post_form
2117-
~get_args:[Eliom_request.nl_template_string, t]
2118-
?cookies_info form uri Eliom_request.string_result
2119-
in
2120-
set_template_content ~replace:false ~uri ?fragment content
2121-
| _ ->
2122-
let uri, content =
2123-
Eliom_request.send_post_form ~expecting_process_page:true
2124-
?cookies_info form uri Eliom_request.xml_result
2125-
in
2126-
set_content ~replace:false ~uri ?fragment content)
2110+
with_progress_cursor (fun () ->
2111+
let form = Js.Unsafe.coerce form in
2112+
let uri, fragment = Url.split_fragment full_uri in
2113+
match tmpl with
2114+
| Some t when tmpl = Eliom_request_info.get_request_template () ->
2115+
let uri, content =
2116+
Eliom_request.send_post_form
2117+
~get_args:[Eliom_request.nl_template_string, t]
2118+
?cookies_info form uri Eliom_request.string_result
2119+
in
2120+
set_template_content ~replace:false ~uri ?fragment content
2121+
| _ ->
2122+
let uri, content =
2123+
Eliom_request.send_post_form ~expecting_process_page:true
2124+
?cookies_info form uri Eliom_request.xml_result
2125+
in
2126+
set_content ~replace:false ~uri ?fragment content)
21272127

21282128
let _ =
21292129
(Eliom_client_core.change_page_uri_ :=
@@ -2189,7 +2189,7 @@ let () =
21892189
Js_of_ocaml_eio.Eio_js.start (fun () ->
21902190
with_progress_cursor
21912191
(* TODO: ciao-lwt: This computation might not be suspended correctly. *)
2192-
@@
2192+
@@ fun () ->
21932193
let uri, fragment = Url.split_fragment full_uri in
21942194
if uri = get_current_uri ()
21952195
then (

src/lib/eliom_client.client.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ val onload : (unit -> unit) -> unit
272272
273273
*)
274274

275-
val lwt_onload : unit -> unit
275+
val onload_promise : unit -> unit Eio.Promise.t
276276
(** Returns a Lwt thread that waits until the next page is loaded. *)
277277

278278
type changepage_event =

src/lib/eliom_client_core.client.ml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,10 @@ let in_onload, broadcast_load_end, wait_load_end, set_loading_phase =
273273
let in_onload () = !loading_phase in
274274
let broadcast_load_end () =
275275
loading_phase := false;
276-
Lwt_condition.broadcast load_end ()
276+
Eio.Condition.broadcast load_end
277277
in
278278
let wait_load_end () =
279-
if !loading_phase
280-
then
281-
Eio.Condition.await (* TODO: ciao-lwt: A mutex must be passed *) load_end
282-
__mutex__
283-
else ()
279+
if !loading_phase then Eio.Condition.await_no_mutex load_end else ()
284280
in
285281
in_onload, broadcast_load_end, wait_load_end, set
286282

0 commit comments

Comments
 (0)