mirror of
https://github.com/ocaml-multicore/eio.git
synced 2025-08-29 00:03:47 -04:00
Fix some MDX warnings about missing ;;
This commit is contained in:
parent
055fe3036e
commit
0370b365ba
18
README.md
18
README.md
@ -156,7 +156,7 @@ let main _env =
|
||||
Switch.top @@ fun sw ->
|
||||
Fibre.both ~sw
|
||||
(fun () -> for x = 1 to 3 do traceln "x = %d" x; Fibre.yield ~sw () done)
|
||||
(fun () -> for y = 1 to 3 do traceln "y = %d" y; Fibre.yield ~sw () done)
|
||||
(fun () -> for y = 1 to 3 do traceln "y = %d" y; Fibre.yield ~sw () done);;
|
||||
```
|
||||
|
||||
```ocaml
|
||||
@ -299,7 +299,7 @@ Here's a simple implementation of `cat` using the standard OCaml functions:
|
||||
output stdout buf 0 got;
|
||||
copy ()
|
||||
in
|
||||
copy ()
|
||||
copy ();;
|
||||
```
|
||||
|
||||
And here is the equivalent using Eio:
|
||||
@ -309,7 +309,7 @@ And here is the equivalent using Eio:
|
||||
Eio_main.run @@ fun env ->
|
||||
Eio.Flow.copy
|
||||
(Eio.Stdenv.stdin env)
|
||||
(Eio.Stdenv.stdout env)
|
||||
(Eio.Stdenv.stdout env);;
|
||||
```
|
||||
|
||||
Testing on a fresh 10G file with [pv](https://www.ivarch.com/programs/pv.shtml) on my machine gives:
|
||||
@ -385,7 +385,7 @@ let main ~net ~addr =
|
||||
# Eio_main.run @@ fun env ->
|
||||
main
|
||||
~net:(Eio.Stdenv.net env)
|
||||
~addr:(`Tcp (Unix.inet_addr_loopback, 8080))
|
||||
~addr:(`Tcp (Unix.inet_addr_loopback, 8080));;
|
||||
+Server ready...
|
||||
+Connecting to server...
|
||||
+Server accepted connection from client
|
||||
@ -466,7 +466,7 @@ let try_mkdir dir path =
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
try_mkdir cwd "dir1";
|
||||
try_mkdir cwd "../dir2";
|
||||
try_mkdir cwd "/tmp/dir3";
|
||||
try_mkdir cwd "/tmp/dir3";;
|
||||
+mkdir "dir1" -> ok
|
||||
+mkdir "../dir2" -> Eio.Dir.Permission_denied("../dir2", _)
|
||||
+mkdir "/tmp/dir3" -> Eio.Dir.Permission_denied("/tmp/dir3", _)
|
||||
@ -483,7 +483,7 @@ The checks also apply to following symlinks:
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
try_write_file cwd "dir1/file1" "A";
|
||||
try_write_file cwd "link-to-dir1/file2" "B";
|
||||
try_write_file cwd "link-to-tmp/file3" "C"
|
||||
try_write_file cwd "link-to-tmp/file3" "C";;
|
||||
+write "dir1/file1" -> ok
|
||||
+write "link-to-dir1/file2" -> ok
|
||||
+write "link-to-tmp/file3" -> Eio.Dir.Permission_denied("link-to-tmp/file3", _)
|
||||
@ -497,7 +497,7 @@ You can use `open_dir` (or `with_open_dir`) to create a restricted capability to
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
Eio.Dir.with_open_dir cwd "dir1" @@ fun dir1 ->
|
||||
try_write_file dir1 "file4" "D";
|
||||
try_write_file dir1 "../file5" "E"
|
||||
try_write_file dir1 "../file5" "E";;
|
||||
+write "file4" -> ok
|
||||
+write "../file5" -> Eio.Dir.Permission_denied("../file5", _)
|
||||
- : unit = ()
|
||||
@ -522,7 +522,7 @@ The standard environment provides a clock with the usual POSIX time:
|
||||
let clock = Eio.Stdenv.clock env in
|
||||
traceln "The time is now %f" (Eio.Time.now clock);
|
||||
Eio.Time.sleep clock 1.0;
|
||||
traceln "The time is now %f" (Eio.Time.now clock)
|
||||
traceln "The time is now %f" (Eio.Time.now clock);;
|
||||
+The time is now 1623940778.270336
|
||||
+The time is now 1623940779.270336
|
||||
- : unit = ()
|
||||
@ -566,7 +566,7 @@ let main ~domain_mgr =
|
||||
<!-- $MDX non-deterministic=output -->
|
||||
```ocaml
|
||||
# Eio_main.run @@ fun env ->
|
||||
main ~domain_mgr:(Eio.Stdenv.domain_mgr env)
|
||||
main ~domain_mgr:(Eio.Stdenv.domain_mgr env);;
|
||||
+Starting CPU-intensive task...
|
||||
+Starting CPU-intensive task...
|
||||
+Finished
|
||||
|
@ -23,7 +23,7 @@ let () =
|
||||
|
||||
```ocaml
|
||||
# Eio_luv.run @@ fun env ->
|
||||
Eio.Flow.copy_string "Hello, world!\n" (Eio.Stdenv.stdout env)
|
||||
Eio.Flow.copy_string "Hello, world!\n" (Eio.Stdenv.stdout env);;
|
||||
Hello, world!
|
||||
- : unit = ()
|
||||
```
|
||||
@ -41,7 +41,7 @@ let main _stdenv =
|
||||
```
|
||||
|
||||
```ocaml
|
||||
# Eio_luv.run main
|
||||
# Eio_luv.run main;;
|
||||
+Read "\000\000\000\000"
|
||||
- : unit = ()
|
||||
```
|
||||
|
@ -19,7 +19,7 @@ Spawning a second domain:
|
||||
```ocaml
|
||||
# run @@ fun mgr ->
|
||||
let response = Eio.Domain_manager.run_compute_unsafe mgr (fun () -> "Hello from new domain") in
|
||||
traceln "Got %S from spawned domain" response
|
||||
traceln "Got %S from spawned domain" response;;
|
||||
+Got "Hello from new domain" from spawned domain
|
||||
- : unit = ()
|
||||
```
|
||||
@ -28,7 +28,7 @@ The domain raises an exception:
|
||||
|
||||
```ocaml
|
||||
# run @@ fun mgr ->
|
||||
Eio.Domain_manager.run_compute_unsafe mgr (fun () -> failwith "Exception from new domain")
|
||||
Eio.Domain_manager.run_compute_unsafe mgr (fun () -> failwith "Exception from new domain");;
|
||||
Exception: Failure "Exception from new domain".
|
||||
```
|
||||
|
||||
@ -54,7 +54,7 @@ Here, we use a mutex to check that the parent domain really did run while waitin
|
||||
(fun () ->
|
||||
traceln "Other fibres can still run";
|
||||
Mutex.unlock mutex
|
||||
)
|
||||
);;
|
||||
+Spawning new domain...
|
||||
+Other fibres can still run
|
||||
+Got "Hello from new domain" from spawned domain
|
||||
|
@ -56,7 +56,7 @@ Creating a file and reading it back:
|
||||
# run @@ fun ~sw env ->
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
write_file ~sw ~create:(`Exclusive 0o666) cwd "test-file" "my-data";
|
||||
traceln "Got %S" @@ read_file ~sw cwd "test-file"
|
||||
traceln "Got %S" @@ read_file ~sw cwd "test-file";;
|
||||
+Got "my-data"
|
||||
- : unit = ()
|
||||
```
|
||||
@ -75,7 +75,7 @@ Trying to use cwd to access a file outside of that subtree fails:
|
||||
# run @@ fun ~sw env ->
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
write_file ~sw ~create:(`Exclusive 0o666) cwd "../test-file" "my-data";
|
||||
failwith "Should have failed"
|
||||
failwith "Should have failed";;
|
||||
Exception: Eio.Dir.Permission_denied ("../test-file", _)
|
||||
```
|
||||
|
||||
@ -84,7 +84,7 @@ Trying to use cwd to access an absolute path fails:
|
||||
# run @@ fun ~sw env ->
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
write_file ~sw ~create:(`Exclusive 0o666) cwd "/tmp/test-file" "my-data";
|
||||
failwith "Should have failed"
|
||||
failwith "Should have failed";;
|
||||
Exception: Eio.Dir.Permission_denied ("/tmp/test-file", _)
|
||||
```
|
||||
|
||||
@ -96,7 +96,7 @@ Exclusive create fails if already exists:
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
write_file ~sw ~create:(`Exclusive 0o666) cwd "test-file" "first-write";
|
||||
write_file ~sw ~create:(`Exclusive 0o666) cwd "test-file" "first-write";
|
||||
failwith "Should have failed"
|
||||
failwith "Should have failed";;
|
||||
Exception: Eio.Dir.Already_exists ("test-file", _)
|
||||
```
|
||||
|
||||
@ -106,7 +106,7 @@ If-missing create succeeds if already exists:
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
write_file ~sw ~create:(`If_missing 0o666) cwd "test-file" "1st-write-original";
|
||||
write_file ~sw ~create:(`If_missing 0o666) cwd "test-file" "2nd-write";
|
||||
traceln "Got %S" @@ read_file ~sw cwd "test-file"
|
||||
traceln "Got %S" @@ read_file ~sw cwd "test-file";;
|
||||
+Got "2nd-write-original"
|
||||
- : unit = ()
|
||||
```
|
||||
@ -117,7 +117,7 @@ Truncate create succeeds if already exists, and truncates:
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
write_file ~sw ~create:(`Or_truncate 0o666) cwd "test-file" "1st-write-original";
|
||||
write_file ~sw ~create:(`Or_truncate 0o666) cwd "test-file" "2nd-write";
|
||||
traceln "Got %S" @@ read_file ~sw cwd "test-file"
|
||||
traceln "Got %S" @@ read_file ~sw cwd "test-file";;
|
||||
+Got "2nd-write"
|
||||
- : unit = ()
|
||||
# Unix.unlink "test-file";;
|
||||
@ -129,7 +129,7 @@ Error if no create and doesn't exist:
|
||||
# run @@ fun ~sw env ->
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
write_file ~sw ~create:`Never cwd "test-file" "1st-write-original";
|
||||
traceln "Got %S" @@ read_file ~sw cwd "test-file"
|
||||
traceln "Got %S" @@ read_file ~sw cwd "test-file";;
|
||||
Exception: Eio.Dir.Not_found ("test-file", _)
|
||||
```
|
||||
|
||||
@ -139,7 +139,7 @@ Appending to an existing file:
|
||||
let cwd = Eio.Stdenv.cwd env in
|
||||
write_file ~sw ~create:(`Or_truncate 0o666) cwd "test-file" "1st-write-original";
|
||||
write_file ~sw ~create:`Never ~append:true cwd "test-file" "2nd-write";
|
||||
traceln "Got %S" @@ read_file ~sw cwd "test-file"
|
||||
traceln "Got %S" @@ read_file ~sw cwd "test-file";;
|
||||
+Got "1st-write-original2nd-write"
|
||||
- : unit = ()
|
||||
# Unix.unlink "test-file";;
|
||||
@ -154,7 +154,7 @@ Appending to an existing file:
|
||||
try_mkdir cwd "subdir";
|
||||
try_mkdir cwd "subdir/nested";
|
||||
write_file ~sw ~create:(`Exclusive 0o600) cwd "subdir/nested/test-file" "data";
|
||||
()
|
||||
();;
|
||||
+mkdir "subdir" -> ok
|
||||
+mkdir "subdir/nested" -> ok
|
||||
- : unit = ()
|
||||
@ -178,7 +178,7 @@ Creating directories with nesting, symlinks, etc:
|
||||
try_mkdir cwd "../foo";
|
||||
try_mkdir cwd "to-subdir";
|
||||
try_mkdir cwd "dangle/foo";
|
||||
()
|
||||
();;
|
||||
+mkdir "subdir" -> ok
|
||||
+mkdir "to-subdir/nested" -> ok
|
||||
+mkdir "to-root/tmp/foo" -> Eio.Dir.Permission_denied ("to-root/tmp/foo", _)
|
||||
@ -198,7 +198,7 @@ Create a sandbox, write a file with it, then read it from outside:
|
||||
let subdir = Eio.Dir.open_dir ~sw cwd "sandbox" in
|
||||
write_file ~sw ~create:(`Exclusive 0o600) subdir "test-file" "data";
|
||||
try_mkdir subdir "../new-sandbox";
|
||||
traceln "Got %S" @@ read_file ~sw cwd "sandbox/test-file"
|
||||
traceln "Got %S" @@ read_file ~sw cwd "sandbox/test-file";;
|
||||
+mkdir "sandbox" -> ok
|
||||
+mkdir "../new-sandbox" -> Eio.Dir.Permission_denied ("../new-sandbox", _)
|
||||
+Got "data"
|
||||
@ -222,7 +222,7 @@ Using `cwd` we can't access the parent, but using `fs` we can:
|
||||
try_write_file ~sw ~create:(`Exclusive 0o600) fs "../test-file" "data";
|
||||
);
|
||||
Unix.unlink "test-file";
|
||||
Unix.rmdir "outside-cwd"
|
||||
Unix.rmdir "outside-cwd";;
|
||||
+mkdir "fs-test" -> ok
|
||||
+chdir "fs-test"
|
||||
+mkdir "../outside-cwd" -> Eio.Dir.Permission_denied ("../outside-cwd", _)
|
||||
|
@ -68,7 +68,7 @@ let test_address addr ~net sw =
|
||||
Handling one connection, then cancelling the server:
|
||||
|
||||
```ocaml
|
||||
# run (test_address addr)
|
||||
# run (test_address addr);;
|
||||
+Connecting to server...
|
||||
+Server accepted connection from client
|
||||
+Server received: "Hello from client"
|
||||
@ -80,7 +80,7 @@ Exception: Graceful_shutdown.
|
||||
Handling one connection on a Unix domain socket:
|
||||
|
||||
```ocaml
|
||||
# run (test_address (`Unix "/tmp/eio-test.sock"))
|
||||
# run (test_address (`Unix "/tmp/eio-test.sock"));;
|
||||
+Connecting to server...
|
||||
+Server accepted connection from client
|
||||
+Server received: "Hello from client"
|
||||
@ -93,7 +93,7 @@ Handling one connection on an abstract Unix domain socket (this only works on Li
|
||||
|
||||
<!-- $MDX non-deterministic=command -->
|
||||
```ocaml
|
||||
# run (test_address (`Unix "\x00/tmp/eio-test.sock"))
|
||||
# run (test_address (`Unix "\x00/tmp/eio-test.sock"));;
|
||||
+Connecting to server...
|
||||
+Server accepted connection from client
|
||||
+Server received: "Hello from client"
|
||||
@ -126,7 +126,7 @@ Cancelling the read:
|
||||
Switch.turn_off read_switch Graceful_shutdown;
|
||||
let msg = read_all flow in
|
||||
traceln "Client received: %S" msg
|
||||
)
|
||||
);;
|
||||
+Connecting to server...
|
||||
+Connection opened - cancelling server's read
|
||||
+Client received: "Request cancelled"
|
||||
@ -140,6 +140,6 @@ Calling accept when the switch is already off:
|
||||
let server = Eio.Net.listen net ~sw ~reuse_addr:true ~backlog:5 addr in
|
||||
Switch.turn_off sw (Failure "Simulated error");
|
||||
Eio.Net.accept_sub server ~sw (fun ~sw:_ _flow _addr -> assert false)
|
||||
~on_error:raise
|
||||
~on_error:raise;;
|
||||
Exception: Failure "Simulated error".
|
||||
```
|
||||
|
@ -35,7 +35,7 @@ Simple non-blocking case
|
||||
add t 1;
|
||||
add t 2;
|
||||
take t;
|
||||
take t
|
||||
take t;;
|
||||
+Adding 1 to stream
|
||||
+Added 1 to stream
|
||||
+Adding 2 to stream
|
||||
@ -56,7 +56,7 @@ Readers have to wait when the stream is empty:
|
||||
add t 1;
|
||||
Fibre.both ~sw
|
||||
(fun () -> take t; take t)
|
||||
(fun () -> add t 2)
|
||||
(fun () -> add t 2);;
|
||||
+Adding 1 to stream
|
||||
+Added 1 to stream
|
||||
+Reading from stream
|
||||
@ -86,7 +86,7 @@ Writers have to wait when the stream is full:
|
||||
take t;
|
||||
take t;
|
||||
take t
|
||||
)
|
||||
);;
|
||||
+Adding 1 to stream
|
||||
+Added 1 to stream
|
||||
+Adding 2 to stream
|
||||
@ -120,7 +120,7 @@ A zero-length queue is synchronous:
|
||||
(fun () ->
|
||||
take t;
|
||||
take t;
|
||||
)
|
||||
);;
|
||||
+Adding 1 to stream
|
||||
+Reading from stream
|
||||
+Got 1 from stream
|
||||
@ -146,7 +146,7 @@ Cancel reading from a stream:
|
||||
with Cancel ->
|
||||
traceln "Cancelled";
|
||||
add t 2;
|
||||
take t
|
||||
take t;;
|
||||
+Reading from stream
|
||||
+Cancelled
|
||||
+Adding 2 to stream
|
||||
@ -171,7 +171,7 @@ Cancel writing to a stream:
|
||||
traceln "Cancelled";
|
||||
take t;
|
||||
add t 3;
|
||||
take t
|
||||
take t;;
|
||||
+Adding 1 to stream
|
||||
+Added 1 to stream
|
||||
+Adding 2 to stream
|
||||
@ -201,7 +201,7 @@ Cancel writing to a zero-length stream:
|
||||
Switch.top @@ fun sw ->
|
||||
Fibre.both ~sw
|
||||
(fun () -> add ~sw t 2)
|
||||
(fun () -> take ~sw t)
|
||||
(fun () -> take ~sw t);;
|
||||
+Adding 1 to stream
|
||||
+Cancelled
|
||||
+Adding 2 to stream
|
||||
@ -219,7 +219,7 @@ Trying to use a stream with a turned-off switch:
|
||||
Switch.top @@ fun sw ->
|
||||
Switch.turn_off sw Cancel;
|
||||
begin try add ~sw t 1 with ex -> traceln "%a" Fmt.exn ex end;
|
||||
begin try take ~sw t with ex -> traceln "%a" Fmt.exn ex end
|
||||
begin try take ~sw t with ex -> traceln "%a" Fmt.exn ex end;;
|
||||
+Adding 1 to stream
|
||||
+Cancelled: Cancel
|
||||
+Reading from stream
|
||||
@ -238,7 +238,7 @@ Readers queue up:
|
||||
Fibre.fork_ignore ~sw (fun () -> take t; traceln "c done");
|
||||
add t 1;
|
||||
add t 2;
|
||||
add t 3
|
||||
add t 3;;
|
||||
+Reading from stream
|
||||
+Reading from stream
|
||||
+Reading from stream
|
||||
@ -268,7 +268,7 @@ Writers queue up:
|
||||
Fibre.fork_ignore ~sw (fun () -> add t 3);
|
||||
take t;
|
||||
take t;
|
||||
take t
|
||||
take t;;
|
||||
+Adding 1 to stream
|
||||
+Adding 2 to stream
|
||||
+Adding 3 to stream
|
||||
|
@ -19,7 +19,7 @@ A very basic example:
|
||||
```ocaml
|
||||
# run (fun _sw ->
|
||||
traceln "Running"
|
||||
);
|
||||
);;
|
||||
+Running
|
||||
- : unit = ()
|
||||
```
|
||||
@ -31,7 +31,7 @@ Turning off a switch still allows you to perform clean-up operations:
|
||||
traceln "Running";
|
||||
Switch.turn_off sw (Failure "Cancel");
|
||||
traceln "Clean up"
|
||||
);
|
||||
);;
|
||||
+Running
|
||||
+Clean up
|
||||
Exception: Failure "Cancel".
|
||||
@ -44,7 +44,7 @@ Exception: Failure "Cancel".
|
||||
Fibre.both ~sw
|
||||
(fun () -> for i = 1 to 2 do traceln "i = %d" i; Fibre.yield ~sw () done)
|
||||
(fun () -> for j = 1 to 2 do traceln "j = %d" j; Fibre.yield ~sw () done)
|
||||
);
|
||||
);;
|
||||
+i = 1
|
||||
+j = 1
|
||||
+i = 2
|
||||
@ -59,7 +59,7 @@ Exception: Failure "Cancel".
|
||||
Fibre.both ~sw
|
||||
(fun () -> for i = 1 to 5 do traceln "i = %d" i; Fibre.yield ~sw () done)
|
||||
(fun () -> failwith "Failed")
|
||||
)
|
||||
);;
|
||||
+i = 1
|
||||
Exception: Failure "Failed".
|
||||
```
|
||||
@ -71,7 +71,7 @@ Exception: Failure "Failed".
|
||||
Fibre.both ~sw
|
||||
(fun () -> Fibre.yield ~sw (); failwith "Failed")
|
||||
(fun () -> for i = 1 to 5 do traceln "i = %d" i; Fibre.yield ~sw () done)
|
||||
)
|
||||
);;
|
||||
+i = 1
|
||||
Exception: Failure "Failed".
|
||||
```
|
||||
@ -82,7 +82,7 @@ Exception: Failure "Failed".
|
||||
# run (fun sw ->
|
||||
Fibre.both ~sw (fun () -> failwith "Failed") ignore;
|
||||
traceln "Not reached"
|
||||
)
|
||||
);;
|
||||
Exception: Failure "Failed".
|
||||
```
|
||||
|
||||
@ -92,7 +92,7 @@ Exception: Failure "Failed".
|
||||
# run (fun sw ->
|
||||
Fibre.both ~sw ignore (fun () -> failwith "Failed");
|
||||
traceln "not reached"
|
||||
)
|
||||
);;
|
||||
Exception: Failure "Failed".
|
||||
```
|
||||
|
||||
@ -103,7 +103,7 @@ Exception: Failure "Failed".
|
||||
Fibre.both ~sw
|
||||
(fun () -> failwith "Failed 1")
|
||||
(fun () -> failwith "Failed 2")
|
||||
)
|
||||
);;
|
||||
Exception: Multiple exceptions:
|
||||
Failure("Failed 1")
|
||||
and
|
||||
@ -117,7 +117,7 @@ The switch is already turned off when we try to fork. The new fibre doesn't star
|
||||
Switch.turn_off sw (Failure "Cancel");
|
||||
Fibre.fork_ignore ~sw (fun () -> traceln "Not reached");
|
||||
traceln "Main continues"
|
||||
)
|
||||
);;
|
||||
+Main continues
|
||||
Exception: Failure "Cancel".
|
||||
```
|
||||
@ -128,9 +128,9 @@ You can't use a switch after leaving its scope:
|
||||
# let sw =
|
||||
let x = ref None in
|
||||
run (fun sw -> x := Some sw);
|
||||
Option.get !x
|
||||
Option.get !x;;
|
||||
val sw : Switch.t = <abstr>
|
||||
# Switch.check sw
|
||||
# Switch.check sw;;
|
||||
Exception: Invalid_argument "Switch finished!".
|
||||
```
|
||||
|
||||
@ -147,7 +147,7 @@ Turning off a switch runs the cancel callbacks, unless they've been removed by t
|
||||
Switch.remove_hook h1;
|
||||
Switch.remove_hook h3;
|
||||
Switch.remove_hook h4
|
||||
)
|
||||
);;
|
||||
+Cancel 3
|
||||
+Cancel 1
|
||||
+Cancel 4
|
||||
@ -161,7 +161,7 @@ Wait for either a promise or a switch; switch cancelled first:
|
||||
Fibre.fork_ignore ~sw (fun () -> traceln "Waiting"; Promise.await ~sw p; traceln "Resolved");
|
||||
Switch.turn_off sw (Failure "Cancelled");
|
||||
Promise.fulfill r ()
|
||||
)
|
||||
);;
|
||||
+Waiting
|
||||
Exception: Failure "Cancelled".
|
||||
```
|
||||
@ -176,7 +176,7 @@ Wait for either a promise or a switch; promise resolves first:
|
||||
Fibre.yield ();
|
||||
traceln "Now cancelling...";
|
||||
Switch.turn_off sw (Failure "Cancelled")
|
||||
);
|
||||
);;
|
||||
+Waiting
|
||||
+Resolved
|
||||
+Now cancelling...
|
||||
@ -191,7 +191,7 @@ Wait for either a promise or a switch; switch cancelled first. Result version.
|
||||
Fibre.fork_ignore ~sw (fun () -> traceln "Waiting"; ignore (Promise.await_result ~sw p); traceln "Resolved");
|
||||
Switch.turn_off sw (Failure "Cancelled");
|
||||
Promise.fulfill r ()
|
||||
);
|
||||
);;
|
||||
+Waiting
|
||||
Exception: Failure "Cancelled".
|
||||
```
|
||||
@ -205,7 +205,7 @@ Wait for either a promise or a switch; promise resolves first but switch off wit
|
||||
Promise.fulfill r ();
|
||||
traceln "Now cancelling...";
|
||||
Switch.turn_off sw (Failure "Cancelled")
|
||||
)
|
||||
);;
|
||||
+Waiting
|
||||
+Now cancelling...
|
||||
Exception: Failure "Cancelled".
|
||||
@ -220,7 +220,7 @@ Child switches are cancelled when the parent is cancelled:
|
||||
Fibre.fork_sub_ignore ~sw ~on_error (fun sw -> traceln "Child 1"; Promise.await ~sw p);
|
||||
Fibre.fork_sub_ignore ~sw ~on_error (fun sw -> traceln "Child 2"; Promise.await ~sw p);
|
||||
Switch.turn_off sw (Failure "Cancel parent")
|
||||
)
|
||||
);;
|
||||
+Child 1
|
||||
+Child 2
|
||||
+child: Failure("Cancel parent")
|
||||
@ -241,7 +241,7 @@ A child can fail independently of the parent:
|
||||
Promise.fulfill r2 ();
|
||||
Fibre.yield ~sw ();
|
||||
traceln "Parent fibre is still running"
|
||||
)
|
||||
);;
|
||||
+Child 1
|
||||
+Child 2
|
||||
+child: Failure("Child error")
|
||||
@ -264,7 +264,7 @@ A child can be cancelled independently of the parent:
|
||||
Switch.turn_off (Option.get !child) (Failure "Cancel child");
|
||||
Fibre.yield ~sw ();
|
||||
traceln "Parent fibre is still running"
|
||||
);
|
||||
);;
|
||||
+Child 1
|
||||
+child: Failure("Cancel child")
|
||||
+Parent fibre is still running
|
||||
@ -281,7 +281,7 @@ A child error handle raises:
|
||||
Promise.break r (Failure "Child error escapes");
|
||||
Fibre.yield ~sw ();
|
||||
traceln "Not reached"
|
||||
)
|
||||
);;
|
||||
+Child
|
||||
Exception: Failure "Child error escapes".
|
||||
```
|
||||
@ -293,7 +293,7 @@ A child error handler deals with the exception:
|
||||
let print ex = traceln "%s" (Printexc.to_string ex); 0 in
|
||||
let x = Switch.sub sw ~on_error:print (fun _sw -> failwith "Child error") in
|
||||
traceln "x = %d" x
|
||||
)
|
||||
);;
|
||||
+Failure("Child error")
|
||||
+x = 0
|
||||
- : unit = ()
|
||||
@ -305,7 +305,7 @@ The system deadlocks. The scheduler detects and reports this:
|
||||
# run (fun sw ->
|
||||
let p, _ = Promise.create () in
|
||||
Promise.await ~sw p
|
||||
)
|
||||
);;
|
||||
Exception:
|
||||
Failure
|
||||
"Deadlock detected: no events scheduled but main function hasn't returned".
|
||||
@ -319,7 +319,7 @@ Release on success:
|
||||
# run (fun sw ->
|
||||
Switch.on_release sw (fun () -> traceln "release 1");
|
||||
Switch.on_release sw (fun () -> traceln "release 2");
|
||||
)
|
||||
);;
|
||||
+release 2
|
||||
+release 1
|
||||
- : unit = ()
|
||||
@ -332,7 +332,7 @@ Release on error:
|
||||
Switch.on_release sw (fun () -> traceln "release 1");
|
||||
Switch.on_release sw (fun () -> traceln "release 2");
|
||||
failwith "Test error"
|
||||
)
|
||||
);;
|
||||
+release 2
|
||||
+release 1
|
||||
Exception: Failure "Test error".
|
||||
@ -345,7 +345,7 @@ A release operation itself fails:
|
||||
Switch.on_release sw (fun () -> traceln "release 1"; failwith "failure 1");
|
||||
Switch.on_release sw (fun () -> traceln "release 2");
|
||||
Switch.on_release sw (fun () -> traceln "release 3"; failwith "failure 3");
|
||||
)
|
||||
);;
|
||||
+release 3
|
||||
+release 2
|
||||
+release 1
|
||||
@ -375,7 +375,7 @@ Using switch from inside release handler:
|
||||
);
|
||||
);
|
||||
traceln "Main fibre done"
|
||||
)
|
||||
);;
|
||||
+Main fibre done
|
||||
+Starting release 2
|
||||
+Starting release 1
|
||||
@ -400,7 +400,7 @@ We release when `fork_sub_ignore` returns:
|
||||
```ocaml
|
||||
# run (fun sw ->
|
||||
fork_sub_ignore_resource sw
|
||||
)
|
||||
);;
|
||||
+Allocate resource
|
||||
+Child fibre running
|
||||
+Free resource
|
||||
@ -413,7 +413,7 @@ We release when `fork_sub_ignore` fails due to parent switch being already off:
|
||||
# run (fun sw ->
|
||||
Switch.turn_off sw (Failure "Switch already off");
|
||||
fork_sub_ignore_resource sw
|
||||
)
|
||||
);;
|
||||
+Allocate resource
|
||||
+Free resource
|
||||
Exception: Failure "Switch already off".
|
||||
@ -426,7 +426,7 @@ We release when `fork_sub_ignore` fails due to parent switch being invalid:
|
||||
let copy = ref sw in
|
||||
Switch.sub sw ~on_error:raise (fun sub -> copy := sub);
|
||||
fork_sub_ignore_resource !copy
|
||||
)
|
||||
);;
|
||||
+Allocate resource
|
||||
+Free resource
|
||||
Exception: Invalid_argument "Switch finished!".
|
||||
@ -440,7 +440,7 @@ We release when `fork_sub_ignore`'s switch is turned off while running:
|
||||
Fibre.fork_sub_ignore ~sw ~on_error:raise
|
||||
~on_release:(fun () -> traceln "Free resource")
|
||||
(fun _sw -> failwith "Simulated error")
|
||||
)
|
||||
);;
|
||||
+Allocate resource
|
||||
+Free resource
|
||||
Exception: Failure "Simulated error".
|
||||
|
@ -30,7 +30,7 @@ Create a promise, fork a thread waiting for it, then fulfull it:
|
||||
traceln "Thread before yield: %a" (pp_promise Fmt.string) thread;
|
||||
Fibre.yield ();
|
||||
traceln "Thread after yield: %a" (pp_promise Fmt.string) thread;
|
||||
traceln "Final result: %s" (Promise.await thread)
|
||||
traceln "Final result: %s" (Promise.await thread);;
|
||||
+Initial state: unresolved
|
||||
+After being fulfilled: fulfilled:ok
|
||||
+Thread before yield: unresolved
|
||||
@ -53,7 +53,7 @@ Create a promise, fork a thread waiting for it, then break it:
|
||||
traceln "Thread after yield: %a" (pp_promise Fmt.string) thread;
|
||||
match Promise.await thread with
|
||||
| x -> failwith x
|
||||
| exception (Failure msg) -> traceln "Final result exception: %s" msg
|
||||
| exception (Failure msg) -> traceln "Final result exception: %s" msg;;
|
||||
+Initial state: unresolved
|
||||
+After being broken: broken:test
|
||||
+Thread before yield: unresolved
|
||||
@ -79,7 +79,7 @@ Some simple tests of `fork_ignore`:
|
||||
);
|
||||
assert false
|
||||
with Exit ->
|
||||
traceln "Forked code ran; i is now %d" !i
|
||||
traceln "Forked code ran; i is now %d" !i;;
|
||||
+Forked code ran; i is now 1
|
||||
+Forked code waiting; i is still 1
|
||||
+Forked code ran; i is now 2
|
||||
@ -115,7 +115,7 @@ Basic semaphore tests:
|
||||
decr running;
|
||||
Semaphore.release sem;
|
||||
decr running;
|
||||
Semaphore.release sem
|
||||
Semaphore.release sem;;
|
||||
+Semaphore means that only 2 threads are running
|
||||
+One finished; now 1 is running
|
||||
+Yield allows C to start; now 2 are running
|
||||
@ -136,7 +136,7 @@ Releasing a semaphore when no-one is waiting for it:
|
||||
Semaphore.release sem; (* Release with a non-empty wait-queue *)
|
||||
traceln "Now b running: %d" (Semaphore.get_value sem);
|
||||
Semaphore.release sem; (* Release with an empty wait-queue *)
|
||||
traceln "Finished: %d" (Semaphore.get_value sem)
|
||||
traceln "Finished: %d" (Semaphore.get_value sem);;
|
||||
+Initial config: 1
|
||||
+A running: 0
|
||||
+Now b running: 0
|
||||
|
@ -22,7 +22,7 @@ Check sleep works:
|
||||
let t0 = Unix.gettimeofday () in
|
||||
Eio.Time.sleep clock 0.01;
|
||||
let t1 = Unix.gettimeofday () in
|
||||
assert (t1 -. t0 >= 0.01)
|
||||
assert (t1 -. t0 >= 0.01);;
|
||||
- : unit = ()
|
||||
```
|
||||
|
||||
@ -34,7 +34,7 @@ Check sleep works with a switch:
|
||||
let t0 = Unix.gettimeofday () in
|
||||
Eio.Time.sleep ~sw clock 0.01;
|
||||
let t1 = Unix.gettimeofday () in
|
||||
assert (t1 -. t0 >= 0.01)
|
||||
assert (t1 -. t0 >= 0.01);;
|
||||
- : unit = ()
|
||||
```
|
||||
|
||||
@ -45,7 +45,7 @@ Cancelling sleep:
|
||||
Switch.top @@ fun sw ->
|
||||
Fibre.both ~sw
|
||||
(fun () -> Eio.Time.sleep ~sw clock 1200.; assert false)
|
||||
(fun () -> Switch.turn_off sw (Failure "Simulated cancel"))
|
||||
(fun () -> Switch.turn_off sw (Failure "Simulated cancel"));;
|
||||
Exception: Failure "Simulated cancel".
|
||||
```
|
||||
|
||||
@ -56,7 +56,7 @@ Switch is already off:
|
||||
Switch.top @@ fun sw ->
|
||||
Switch.turn_off sw (Failure "Simulated failure");
|
||||
Eio.Time.sleep ~sw clock 1200.0;
|
||||
assert false
|
||||
assert false;;
|
||||
Exception: Failure "Simulated failure".
|
||||
```
|
||||
|
||||
@ -67,7 +67,7 @@ Scheduling a timer that's already due:
|
||||
Switch.top @@ fun sw ->
|
||||
Fibre.both ~sw
|
||||
(fun () -> traceln "First fibre runs"; Eio.Time.sleep ~sw clock (-1.0); traceln "Sleep done")
|
||||
(fun () -> traceln "Second fibre runs")
|
||||
(fun () -> traceln "Second fibre runs");;
|
||||
+First fibre runs
|
||||
+Second fibre runs
|
||||
+Sleep done
|
||||
@ -88,7 +88,7 @@ Check ordering works:
|
||||
Eio.Time.sleep clock 0.1;
|
||||
traceln "Short timer finished";
|
||||
Switch.turn_off sw (Failure "Simulated cancel")
|
||||
)
|
||||
);;
|
||||
+Short timer finished
|
||||
Exception: Failure "Simulated cancel".
|
||||
```
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Eio_main.run @@ fun _env ->
|
||||
traceln "One-line trace";
|
||||
traceln "@[<v2>A nested list@,Foo@,Bar@]";
|
||||
traceln "Trace with position" ~__POS__:("test_trace.md", 5, 1, 10);
|
||||
traceln "Trace with position" ~__POS__:("test_trace.md", 5, 1, 10);;
|
||||
+One-line trace
|
||||
+A nested list
|
||||
+ Foo
|
||||
|
Loading…
x
Reference in New Issue
Block a user