Skip to content

Commit a1d9132

Browse files
authored
Merge pull request #20 from Julow/lwt_io_for_ocsipersist
Support more `Lwt_io` operations
2 parents 98827ed + 026c682 commit a1d9132

File tree

6 files changed

+223
-45
lines changed

6 files changed

+223
-45
lines changed

bin/lwt_to_direct_style/ast_rewrite.ml

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ let rewrite_apply_lwt ~backend ~state ident args =
280280
("[<?>] can't be automatically translated."
281281
^ backend#choose_comment_hint);
282282
return None
283+
| "wrap" ->
284+
take @@ fun f -> return (Some (Exp.apply f [ (Nolabel, mk_unit_val) ]))
283285
| _ -> return None
284286

285287
let string_drop_suffix ~suffix s =
@@ -312,6 +314,17 @@ let rewrite_apply ~backend ~state full_ident args =
312314
(( "printf" | "eprintf" | "stdout" | "stderr" | "fprintf" | "kfprintf"
313315
| "ifprintf" | "ikfprintf" ) as ident) ) ->
314316
transparent [ "Format"; ident ]
317+
| ( "Lwt_unix",
318+
(( "socket" | "socketpair" | "listen" | "shutdown" | "getsockname"
319+
| "getpeername" | "waitpid" | "wait4" | "wait" ) as ident) ) ->
320+
transparent [ "Unix"; ident ]
321+
| "Lwt_io", "read_value" -> transparent [ "Marshal"; "from_channel" ]
322+
| "Lwt_io", "write_value" -> transparent [ "Marshal"; "to_channel" ]
323+
| "Lwt_unix", (("connect" | "accept" | "bind") as ident) ->
324+
Printf.ksprintf (add_comment state)
325+
"This call to [Unix.%s] was [Lwt_unix.%s] before. It's now blocking."
326+
ident ident;
327+
transparent [ "Unix"; ident ]
315328
| "Lwt_list", ident -> (
316329
match string_drop_suffix ~suffix:"_s" ident with
317330
| Some ident -> transparent [ "List"; ident ]
@@ -356,12 +369,13 @@ let rewrite_apply ~backend ~state full_ident args =
356369
| "Lwt_mutex", "with_lock" ->
357370
take @@ fun t ->
358371
take @@ fun f -> return (Some (backend#mutex_with_lock t f))
359-
| "Lwt_io", "read_into" ->
372+
| "Lwt_io", (("read_into" | "read_into_exactly") as ident) ->
373+
let exactly = ident = "read_into_exactly" in
360374
take @@ fun input ->
361375
take @@ fun buffer ->
362376
take @@ fun buf_off ->
363377
take @@ fun buf_len ->
364-
return (Some (backend#io_read input buffer buf_off buf_len))
378+
return (Some (backend#io_read ~exactly input buffer buf_off buf_len))
365379
| "Lwt_io", "of_fd" ->
366380
ignore_lblarg "buffer"
367381
@@ ignore_lblarg ~cmt:"Will behave as if it was [true]." "close"
@@ -384,8 +398,20 @@ let rewrite_apply ~backend ~state full_ident args =
384398
take @@ fun str -> return (Some (backend#io_write_str chan str))
385399
| "Lwt_io", "length" -> take @@ fun fd -> return (Some (backend#io_length fd))
386400
| "Lwt_io", "close" -> take @@ fun fd -> return (Some (backend#io_close fd))
401+
| "Lwt_io", "flush" -> take @@ fun fd -> return (Some (backend#io_flush fd))
402+
| "Lwt_io", "with_connection" ->
403+
ignore_lblarg "fd" @@ ignore_lblarg "in_buffer"
404+
@@ ignore_lblarg "out_buffer" @@ take
405+
@@ fun sockaddr ->
406+
take @@ fun f -> return (Some (backend#net_with_connection sockaddr f))
387407
| "Lwt_main", "run" ->
388408
take @@ fun promise -> return (Some (backend#main_run promise))
409+
| "Lwt_preemptive", "detach" ->
410+
take @@ fun f ->
411+
take @@ fun arg ->
412+
return
413+
(Some
414+
(backend#domain_detach (mk_thunk (Exp.apply f [ (Nolabel, arg) ]))))
389415
| _ -> return None
390416

391417
(** Transform a [binding_op] into a [pattern] and an [expression] while
@@ -550,6 +576,7 @@ let rewrite_type ~backend ~state typ =
550576
| "group_entry" ) as tname) ),
551577
params ) ->
552578
Some (mk_typ_constr ~params [ "Unix"; tname ])
579+
| ("Lwt_io", "input_channel"), [] -> Some backend#type_in_channel
553580
| ("Lwt_io", "output_channel"), [] -> Some backend#type_out_channel
554581
| _ -> None)
555582
| _ -> None

bin/lwt_to_direct_style/concurrency_backend.ml

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ let eio ~eio_sw_as_fiber_var ~eio_env_as_fiber_var add_comment =
1818
[ i ]
1919
in
2020
let add_comment fmt = Format.kasprintf add_comment fmt in
21-
let add_comment_dropped_exp ~label exp =
22-
add_comment "Dropped expression (%s): [%s]." label
21+
let add_comment_dropped_exp ~label ?(cmt = "") exp =
22+
add_comment "Dropped expression (%s): [%s].%s" label
2323
(Ocamlformat_utils.format_expression exp)
24+
cmt
2425
in
2526
(* If [--eio-sw-as-fiber-var] is passed on the command line, this will query
2627
the current switch. Otherwise, this will generate a comment.
@@ -206,7 +207,7 @@ let eio ~eio_sw_as_fiber_var ~eio_env_as_fiber_var add_comment =
206207
(* ]) *)
207208
fd
208209

209-
method io_read input buffer buf_offset buf_len =
210+
method io_read ~exactly input buffer buf_offset buf_len =
210211
add_comment "[%s] should be a [Cstruct.t]."
211212
(Ocamlformat_utils.format_expression buffer);
212213
add_comment
@@ -215,9 +216,12 @@ let eio ~eio_sw_as_fiber_var ~eio_env_as_fiber_var add_comment =
215216
contains an internal buffer) or change the call to \
216217
[Eio.Buf_read.of_flow] used to create the buffer."
217218
(Ocamlformat_utils.format_expression input);
218-
add_comment_dropped_exp ~label:"buffer offset" buf_offset;
219-
add_comment_dropped_exp ~label:"buffer length" buf_len;
220-
mk_apply_simple [ "Eio"; "Flow"; "single_read" ] [ input; buffer ]
219+
add_comment_dropped_exp ~label:"buffer offset"
220+
~cmt:" This will behave as if it was [0]." buf_offset;
221+
add_comment_dropped_exp ~label:"buffer length"
222+
~cmt:" This will behave as if it was [Cstruct.length buffer]." buf_len;
223+
let fun_ = if exactly then "read_exact" else "single_read" in
224+
mk_apply_simple [ "Eio"; "Flow"; fun_ ] [ input; buffer ]
221225

222226
method io_read_all input =
223227
mk_apply_simple [ "Eio"; "Buf_read"; "take_all" ] [ input ]
@@ -229,6 +233,9 @@ let eio ~eio_sw_as_fiber_var ~eio_env_as_fiber_var add_comment =
229233
unbuffered IO.";
230234
None
231235

236+
method io_flush output =
237+
mk_apply_simple [ "Eio"; "Buf_write"; "flush" ] [ output ]
238+
232239
method fd_close fd =
233240
(* TODO: See [of_unix_file_descr]. mk_apply_simple [ "Eio_unix"; "Fd" ] [ fd ] *)
234241
mk_apply_simple [ "Unix"; "close" ] [ fd ]
@@ -250,7 +257,8 @@ let eio ~eio_sw_as_fiber_var ~eio_env_as_fiber_var add_comment =
250257
in
251258
mk_apply_ident (switch_ident "run")
252259
[
253-
(Labelled (mk_loc "name"), mk_const_string "main");
260+
(* TODO: Add the [~name] argument. Currently commented-out because added in a too recent version of eio.
261+
(Labelled (mk_loc "name"), mk_const_string "main"); *)
254262
(Nolabel, fun_sw);
255263
]
256264
| None -> k
@@ -310,6 +318,7 @@ let eio ~eio_sw_as_fiber_var ~eio_env_as_fiber_var add_comment =
310318
mk_apply_simple [ "Eio"; "Buf_write"; "string" ] [ chan; str ]
311319

312320
method io_close fd = mk_apply_simple [ "Eio"; "Resource"; "close" ] [ fd ]
321+
method type_in_channel = mk_typ_constr [ "Eio"; "Buf_read"; "t" ]
313322
method type_out_channel = mk_typ_constr [ "Eio"; "Buf_write"; "t" ]
314323

315324
method path_stat ~follow path =
@@ -318,4 +327,37 @@ let eio ~eio_sw_as_fiber_var ~eio_env_as_fiber_var add_comment =
318327
(Labelled (mk_loc "follow"), mk_constr_of_bool follow);
319328
(Nolabel, mk_apply_simple [ "Eio"; "Path"; "/" ] [ env "cwd"; path ]);
320329
]
330+
331+
method domain_detach thunk =
332+
mk_apply_ident
333+
(fiber_ident "fork_promise")
334+
[
335+
get_current_switch_arg ();
336+
( Nolabel,
337+
mk_thunk
338+
(mk_apply_simple
339+
[ "Eio"; "Domain_manager"; "run" ]
340+
[ env "domain_mgr"; thunk ]) );
341+
]
342+
343+
method net_with_connection sockaddr f =
344+
add_comment
345+
"[%s] is of type [Unix.sockaddr] but it should be a \
346+
[Eio.Net.Sockaddr.stream]."
347+
(Ocamlformat_utils.format_expression sockaddr);
348+
mk_apply_simple (switch_ident "run")
349+
[
350+
mk_fun ~arg_name:"sw" (fun sw ->
351+
Exp.apply f
352+
[
353+
( Nolabel,
354+
mk_apply_ident
355+
[ "Eio"; "Net"; "connect" ]
356+
[
357+
(Labelled (mk_loc "sw"), sw);
358+
(Nolabel, env "net");
359+
(Nolabel, sockaddr);
360+
] );
361+
]);
362+
]
321363
end

test/lwt_to_direct_style/eio-switch.t/run.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Make a writable directory tree:
4444
let () =
4545
Eio_main.run (fun env ->
4646
Fiber.with_binding Fiber_var.env env (fun () ->
47-
Switch.run ~name:"main" (fun sw ->
47+
Switch.run (fun sw ->
4848
Fiber.with_binding Fiber_var.sw sw (fun () ->
4949
(* TODO: lwt-to-direct-style: [Eio_main.run] argument used to be a [Lwt] promise and is now a [fun]. Make sure no asynchronous or IO calls are done outside of this [fun]. *)
5050
main ()))))

0 commit comments

Comments
 (0)