Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mingw blocks using 2+ threads / unix works ok #3910

Closed
vicuna opened this issue Dec 5, 2005 · 1 comment
Closed

mingw blocks using 2+ threads / unix works ok #3910

vicuna opened this issue Dec 5, 2005 · 1 comment
Assignees
Labels

Comments

@vicuna
Copy link

vicuna commented Dec 5, 2005

Original bug ID: 3910
Reporter: pbljung
Assigned to: @xavierleroy
Status: closed (set by @xavierleroy on 2005-12-07T12:46:53Z)
Resolution: fixed
Priority: normal
Severity: block
Version: 3.08.3
Category: ~DO NOT USE (was: OCaml general)
Monitored by: pbljung

Bug description

Using 1 pair of a sender/receiver threads to synchronize & communicate works fine using ocaml mingw -threads (downloaded precompiled version). However using 2+ independent pairs blocks under mingw. Either Thread.join or Event.sync is not working as expected in mingw ocaml.

Note that using an arbitrary number of thread pairs works fine using linux and macosx using either -threads or -vmthreads.

Also note that multiple threads writing to stdout on mingw results in interleaved/garbage output; running on unix results in (desired) non-interleaved output. Removing all printf statements still results in blocking, indicating that this is a separate issue.

% ocamlmktop -thread -custom -o threadtop unix.cma threads.cma -cclib -lthreads -cclib -lunix
% ./threadtop -I +threads
Objective Caml version 3.08.3

Sys.os_type;;

  • : string = "Unix"

#use "multithread2.ml";;

val sender : int Event.channel -> unit =
val receiver : int Event.channel -> unit =
1 reading
2 sending
2 done
1 read v=2
done all

  • : unit = ()

#use "multithread4.ml";;

val sender : int Event.channel -> unit =
val receiver : int Event.channel -> unit =
3 reading
4 sending
4 done
5 reading
6 sending
6 done
3 read v=4
5 read v=6
done all

  • : unit = ()

Running the above tests fails on mingw! CtrlC does not work, and threadtop must be manually terminated.
$ ocamlmktop -thread -custom -o threadtop unix.cma threads.cma -cclib -lthreads -cclib -lunix
$ threadtop.exe -I +threads
Objective Caml version 3.08.3

Sys.os_type;;

  • : string = "Win32"

#use "multithread2.ml";;

val sender : int Event.channel -> unit =
val receiver : int Event.channel -> unit =
1 readin2 sending
g
2 done
1 read v=2
done all

  • : unit = ()

#use "multithread4.ml";;

val sender : int Event.channel -> unit =
val receiver : int Event.channel -> unit =
3 readin456 srseeenandddiiinnngg

43 done
read v=4
g
6 d5 read v=6
one

Additional information

% cat multithread2.ml
let sender c =
let id = Thread.id (Thread.self()) in
Printf.printf "%i sending\n" id; flush stdout;
Event.sync (Event.send c id);
Printf.printf "%i done\n" id;
flush stdout;;

let receiver c =
let id = Thread.id (Thread.self()) in
Printf.printf "%i reading\n" id; flush stdout;
let v = Event.sync (Event.receive c) in
Printf.printf "%i read v=%i\n" id v; flush stdout;;

let c1 = Event.new_channel() in
let t1,t2 = Thread.create sender c1, Thread.create receiver c1 in
List.iter Thread.join [t1;t2];
Printf.printf "done all\n";;

% cat multithread4.ml
let sender c =
let id = Thread.id (Thread.self()) in
Printf.printf "%i sending\n" id; flush stdout;
Event.sync (Event.send c id);
Printf.printf "%i done\n" id;
flush stdout;;

let receiver c =
let id = Thread.id (Thread.self()) in
Printf.printf "%i reading\n" id; flush stdout;
let v = Event.sync (Event.receive c) in
Printf.printf "%i read v=%i\n" id v; flush stdout;;

let c1,c2 = Event.new_channel(), Event.new_channel() in
let t1,t2,t3,t4 = Thread.create sender c1, Thread.create receiver c1,Thread.create sender c2, Thread.create receiver c2 in
List.iter Thread.join [t1;t2;t3;t4];
Printf.printf "done all\n";;

File attachments

@vicuna
Copy link
Author

vicuna commented Dec 7, 2005

Comment author: @xavierleroy

Behavior reproduced in 3.09.0 both with Mingw and MSVC versions.
The deadlock is in the final Thread.join operations, not in the event-based
communications.
The problem goes away if threads are created with CreateThread instead of
beginthread. Possibly, the early closing of the thread handle performed by
beginthread causes a concurrent WaitForSingleObject to hang.
Applied the fix above to otherlibs/systhreads/win32.c in 3.09 bugfix branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants