You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Original bug ID: 4009 Reporter: berke Status: closed (set by @xavierleroy on 2006-06-13T09:54:05Z) Resolution: won't fix Priority: normal Severity: minor Version: 3.09.2 Category: ~DO NOT USE (was: OCaml general) Monitored by:@mmottl
Bug description
Hello,
I have a program where I create a Unix pipe for inter-thread communication. I know, this sounds weird, but this was the only way to feed back libcamlzip's output to streams without using Stream.from_function which is unbuffered and thus dead slow. I then create input and output channels from the descriptors
of the pipe. Thread 2 then writes data while thread 1 reads it. If the program
terminates before thread 1 has finished writing, under certain conditions, the program will lock at exit. Xavier found that this is due to the exit procedure attempting to acquire locks on thread 2's output channel in order to flush it.
Anyway, here is an example reproducing the problem. Note that fiddling with the timing or the number of lines read or written changes the outcome.
The workaround is to close the input channel before exiting the first thread.
% cat lockup.ml
(* Minimal lock-up example *)
let _ =
let (pr,pw) = Unix.pipe () in
let (ic,oc) = (Unix.in_channel_of_descr pr, Unix.out_channel_of_descr pw) in
let _ = Thread.create
begin fun () ->
let w = String.make 4096 ' ' in
w.[4095] <- '\n';
for i = 1 to 100 do
Printf.eprintf "Wrote line %d\n%!" i;
output_string oc w
done;
close_out oc
end
()
in
for j = 1 to 7 do
ignore (input_line ic);
Printf.printf "Read line %d\n%!" j;
ignore (Unix.select [] [] [] 0.05);
done;
;;
% ocamlopt.opt -thread unix.cmxa threads.cmxa lockup.ml -o lockup
% ./lockup
Wrote line 1
Read line 1
Wrote line 2
Wrote line 3
Wrote line 4
Wrote line 5
Wrote line 6
Wrote line 7
Wrote line 8
Wrote line 9
Wrote line 10
Wrote line 11
Wrote line 12
Wrote line 13
Wrote line 14
Wrote line 15
Wrote line 16
Wrote line 17
Wrote line 18
Read line 2
Wrote line 19
Read line 3
Wrote line 20
Read line 4
Wrote line 21
Read line 5
Wrote line 22
Read line 6
Wrote line 23
Read line 7
Wrote line 24
...
The text was updated successfully, but these errors were encountered:
This is unfortunate, but I don't see any way to avoid this behavior, given that 1- we must lock all blocking operations over channels, and 2- flushing all output channels at exit is highly desirable. So, I'm closing this PR for the time being.
Original bug ID: 4009
Reporter: berke
Status: closed (set by @xavierleroy on 2006-06-13T09:54:05Z)
Resolution: won't fix
Priority: normal
Severity: minor
Version: 3.09.2
Category: ~DO NOT USE (was: OCaml general)
Monitored by: @mmottl
Bug description
Hello,
I have a program where I create a Unix pipe for inter-thread communication. I know, this sounds weird, but this was the only way to feed back libcamlzip's output to streams without using Stream.from_function which is unbuffered and thus dead slow. I then create input and output channels from the descriptors
of the pipe. Thread 2 then writes data while thread 1 reads it. If the program
terminates before thread 1 has finished writing, under certain conditions, the program will lock at exit. Xavier found that this is due to the exit procedure attempting to acquire locks on thread 2's output channel in order to flush it.
Anyway, here is an example reproducing the problem. Note that fiddling with the timing or the number of lines read or written changes the outcome.
The workaround is to close the input channel before exiting the first thread.
% cat lockup.ml
(* Minimal lock-up example *)
let _ =
let (pr,pw) = Unix.pipe () in
let (ic,oc) = (Unix.in_channel_of_descr pr, Unix.out_channel_of_descr pw) in
let _ = Thread.create
begin fun () ->
let w = String.make 4096 ' ' in
w.[4095] <- '\n';
for i = 1 to 100 do
Printf.eprintf "Wrote line %d\n%!" i;
output_string oc w
done;
close_out oc
end
()
in
for j = 1 to 7 do
ignore (input_line ic);
Printf.printf "Read line %d\n%!" j;
ignore (Unix.select [] [] [] 0.05);
done;
;;
% ocamlopt.opt -thread unix.cmxa threads.cmxa lockup.ml -o lockup
% ./lockup
Wrote line 1
Read line 1
Wrote line 2
Wrote line 3
Wrote line 4
Wrote line 5
Wrote line 6
Wrote line 7
Wrote line 8
Wrote line 9
Wrote line 10
Wrote line 11
Wrote line 12
Wrote line 13
Wrote line 14
Wrote line 15
Wrote line 16
Wrote line 17
Wrote line 18
Read line 2
Wrote line 19
Read line 3
Wrote line 20
Read line 4
Wrote line 21
Read line 5
Wrote line 22
Read line 6
Wrote line 23
Read line 7
Wrote line 24
...
The text was updated successfully, but these errors were encountered: