File tree Expand file tree Collapse file tree 11 files changed +229
-118
lines changed Expand file tree Collapse file tree 11 files changed +229
-118
lines changed Original file line number Diff line number Diff line change @@ -107,7 +107,7 @@ let run p =
107107 | result ->
108108 finished () ;
109109 result
110- | exception exn ->
110+ | exception exn when Lwt. is_not_ocaml_runtime_exception exn ->
111111 finished () ;
112112 raise exn
113113
Original file line number Diff line number Diff line change @@ -39,6 +39,14 @@ let () = Lwt_main.run (main ())
3939 [Lwt_main.run] will raise [Failure]. This should be considered a logic
4040 error (i.e., code making such a call is inherently broken).
4141
42+ In addition, note that Lwt does not attempt to catch exceptions thrown by
43+ the OCaml runtime. Specifically, Lwt lets [Out_of_memory] and
44+ [Stack_overflow] exceptions traverse all of its functions and bubble up to
45+ the caller of [Lwt_main.run]. Moreover because these exceptions are left
46+ to traverse the call stack, they leave the internal data-structures in an
47+ inconsistent state. For this reason, calling [Lwt_main.run] again after
48+ such an exception will raise [Failure].
49+
4250 It is not safe to call [Lwt_main.run] in a function registered with
4351 [Stdlib.at_exit], use {!Lwt_main.at_exit} instead. *)
4452
Original file line number Diff line number Diff line change 11(library
22 (name tester)
33 (libraries lwt lwttester)
4- (modules (:standard \ main dummy) ))
4+ (modules
5+ (:standard
6+ \
7+ main
8+ dummy
9+ ocaml_runtime_exc_1
10+ ocaml_runtime_exc_2
11+ ocaml_runtime_exc_3
12+ ocaml_runtime_exc_4
13+ ocaml_runtime_exc_5
14+ ocaml_runtime_exc_6)))
515
616(executable
717 (name dummy)
1323 (libraries lwttester tester)
1424 (modules main))
1525
26+ (executable
27+ (name ocaml_runtime_exc_1)
28+ (libraries lwt lwt.unix)
29+ (modules ocaml_runtime_exc_1))
30+
31+ (executable
32+ (name ocaml_runtime_exc_2)
33+ (libraries lwt lwt.unix)
34+ (modules ocaml_runtime_exc_2))
35+
36+ (executable
37+ (name ocaml_runtime_exc_3)
38+ (libraries lwt lwt.unix)
39+ (modules ocaml_runtime_exc_3))
40+
41+ (executable
42+ (name ocaml_runtime_exc_4)
43+ (libraries lwt lwt.unix)
44+ (modules ocaml_runtime_exc_4))
45+
46+ (executable
47+ (name ocaml_runtime_exc_5)
48+ (libraries lwt lwt.unix)
49+ (modules ocaml_runtime_exc_5))
50+
51+ (executable
52+ (name ocaml_runtime_exc_6)
53+ (libraries lwt lwt.unix)
54+ (modules ocaml_runtime_exc_6))
55+
1656(alias
1757 (name runtest)
1858 (package lwt)
Original file line number Diff line number Diff line change @@ -16,9 +16,3 @@ let () =
1616 Test_lwt_bytes. suite;
1717 Test_sleep_and_timeout. suite;
1818 ]
19-
20- let () =
21- (* tests that cannot be run inside of the test framework because they manage
22- their own Lwt_main.run *)
23- Test_run_and_runtime_exceptions. test () ;
24- ()
Original file line number Diff line number Diff line change 1+ (* This file is part of Lwt, released under the MIT license. See LICENSE.md for
2+ details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
3+
4+ (* OCaml runtime exceptions (out-of-memory, stack-overflow) are fatal in a
5+ different way than other exceptions and they leave the Lwt main loop in an
6+ inconsistent state where it cannot be restarted. Indeed, attempting to call
7+ [Lwt_main.run] again after it has crashed with a runtime exception causes a
8+ "Nested calls to Lwt_main.run are not allowed" error.
9+
10+ For this reason, we run this test as its own executable rather than as part
11+ of a larger suite. *)
12+
13+ open Lwt.Syntax
14+
15+ let test () =
16+ try
17+ let () = Lwt_main. run (
18+ let * () = Lwt. pause () in
19+ if true then raise Out_of_memory else Lwt. return_unit
20+ ) in
21+ Printf. eprintf " Test run+raise failure\n " ;
22+ Stdlib. exit 1
23+ with
24+ | Out_of_memory -> ()
25+
26+ let () = test ()
Original file line number Diff line number Diff line change 1+ (* This file is part of Lwt, released under the MIT license. See LICENSE.md for
2+ details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
3+
4+ (* OCaml runtime exceptions (out-of-memory, stack-overflow) are fatal in a
5+ different way than other exceptions and they leave the Lwt main loop in an
6+ inconsistent state where it cannot be restarted. Indeed, attempting to call
7+ [Lwt_main.run] again after it has crashed with a runtime exception causes a
8+ "Nested calls to Lwt_main.run are not allowed" error.
9+
10+ For this reason, we run this test as its own executable rather than as part
11+ of a larger suite. *)
12+
13+ open Lwt.Syntax
14+
15+ let test () =
16+ try
17+ let () = Lwt_main. run (
18+ let * () = Lwt_unix. sleep 0.001 in
19+ if true then raise Out_of_memory else Lwt. return_unit
20+ ) in
21+ Printf. eprintf " Test run+raise failure\n " ;
22+ Stdlib. exit 1
23+ with
24+ | Out_of_memory -> ()
25+
26+ let () = test ()
27+
Original file line number Diff line number Diff line change 1+ (* This file is part of Lwt, released under the MIT license. See LICENSE.md for
2+ details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
3+
4+ (* OCaml runtime exceptions (out-of-memory, stack-overflow) are fatal in a
5+ different way than other exceptions and they leave the Lwt main loop in an
6+ inconsistent state where it cannot be restarted. Indeed, attempting to call
7+ [Lwt_main.run] again after it has crashed with a runtime exception causes a
8+ "Nested calls to Lwt_main.run are not allowed" error.
9+
10+ For this reason, we run this test as its own executable rather than as part
11+ of a larger suite. *)
12+
13+ open Lwt.Syntax
14+
15+ let test () =
16+ try
17+ let () = Lwt_main. run (
18+ let * () = Lwt. pause () in
19+ Lwt. choose [
20+ (let * () = Lwt. pause () in raise Out_of_memory );
21+ Lwt_unix. sleep 2. ;
22+ ]
23+ ) in
24+ Printf. eprintf " Test run+raise failure\n " ;
25+ Stdlib. exit 1
26+ with
27+ | Out_of_memory -> ()
28+
29+ let () = test ()
30+
31+
Original file line number Diff line number Diff line change 1+ (* This file is part of Lwt, released under the MIT license. See LICENSE.md for
2+ details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
3+
4+ (* OCaml runtime exceptions (out-of-memory, stack-overflow) are fatal in a
5+ different way than other exceptions and they leave the Lwt main loop in an
6+ inconsistent state where it cannot be restarted. Indeed, attempting to call
7+ [Lwt_main.run] again after it has crashed with a runtime exception causes a
8+ "Nested calls to Lwt_main.run are not allowed" error.
9+
10+ For this reason, we run this test as its own executable rather than as part
11+ of a larger suite. *)
12+
13+ open Lwt.Syntax
14+
15+ let test () =
16+ try
17+ let () = Lwt_main. run (
18+ let * () = Lwt. pause () in
19+ Lwt. catch
20+ (fun () -> raise Out_of_memory )
21+ (fun _ -> Lwt. return_unit)
22+ ) in
23+ Printf. eprintf " Test run+raise failure\n " ;
24+ Stdlib. exit 1
25+ with
26+ | Out_of_memory -> ()
27+
28+ let () = test ()
29+
30+
Original file line number Diff line number Diff line change 1+ (* This file is part of Lwt, released under the MIT license. See LICENSE.md for
2+ details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
3+
4+ (* OCaml runtime exceptions (out-of-memory, stack-overflow) are fatal in a
5+ different way than other exceptions and they leave the Lwt main loop in an
6+ inconsistent state where it cannot be restarted. Indeed, attempting to call
7+ [Lwt_main.run] again after it has crashed with a runtime exception causes a
8+ "Nested calls to Lwt_main.run are not allowed" error.
9+
10+ For this reason, we run this test as its own executable rather than as part
11+ of a larger suite. *)
12+
13+ open Lwt.Syntax
14+
15+ let test () =
16+ try
17+ let () = Lwt_main. run (
18+ let * () = Lwt. pause () in
19+ let _ =
20+ Lwt. async
21+ (fun () -> let * () = Lwt. pause () in raise Out_of_memory )
22+ in
23+ Lwt_unix. sleep 0.5
24+ ) in
25+ Printf. eprintf " Test run+raise failure\n " ;
26+ Stdlib. exit 1
27+ with
28+ | Out_of_memory -> ()
29+
30+ let () = test ()
31+
32+
Original file line number Diff line number Diff line change 1+ (* This file is part of Lwt, released under the MIT license. See LICENSE.md for
2+ details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
3+
4+ (* OCaml runtime exceptions (out-of-memory, stack-overflow) are fatal in a
5+ different way than other exceptions and they leave the Lwt main loop in an
6+ inconsistent state where it cannot be restarted. Indeed, attempting to call
7+ [Lwt_main.run] again after it has crashed with a runtime exception causes a
8+ "Nested calls to Lwt_main.run are not allowed" error.
9+
10+ For this reason, we run this test as its own executable rather than as part
11+ of a larger suite. *)
12+
13+ open Lwt.Syntax
14+
15+ let test () =
16+ try
17+ let () = Lwt_main. run (
18+ let * () = Lwt. pause () in
19+ let _ =
20+ Lwt. dont_wait
21+ (fun () -> let * () = Lwt. pause () in raise Out_of_memory )
22+ (fun _ -> () )
23+ in
24+ Lwt_unix. sleep 0.5
25+ ) in
26+ Printf. eprintf " Test run+raise failure\n " ;
27+ Stdlib. exit 1
28+ with
29+ | Out_of_memory -> ()
30+
31+ let () = test ()
32+
33+
You can’t perform that action at this time.
0 commit comments