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
Thread.sigmask not working under pthreads #4127
Comments
Comment author: @xavierleroy I confirm the problem. It comes from the fact that the set of pending signals is global rather than per-thread. There is no easy fix, but I keep that in my to do list. |
Comment author: @xavierleroy I've been sleeping on this PR for way too long, so I'm un-assigning it from me. Here is my analysis. The kernel delivers the signal to one of the threads that doesn't block it. However, if this thread is outside a blocking section, it cannot act on it immediately and instead records the signal as pending in a global data structure. Other threads poll this data structure periodically and can decide to handle the signal even if they block it themselves (or, more exactly, blocked it at the time the signal was received). In effect, Thread.sigmask is useless. |
Comment author: @mshinwell Jeremie has been kindly volunteered to think about this. |
Comment author: @diml From my experience, the most reliable way to deal with signals in a multi-threaded program is to handle them from a single thread with [Thread.wait_signal] and redirect signals to this particular thread if they are received from another thread, using a pure C signal handler. This is from a project where I did this: -----[ ml code ]----- external init_signal_manager_thread : unit -> unit = "lt_term_init_signal_manager_thread" let signal_manager_loop () = let init () = ignore (Thread.create signal_manager_loop () : Thread.t) -----[ C code ]----- static pthread_t signal_manager_thread = 0; CAMLprim value lt_term_init_signal_manager_thread() static void handle_signal(int signum) Then [process_signal] is free to handle or deliver the signal to another thread via some other mechanism. I think that this is even better than handling signals directly in a single-thread application, since you know exactly the context in which the code processing the signal will be executed. Fixing this ticket seems like it would be complicated, and even if it's fixed it doesn't help programmers as they have to be extremely careful about what they do from a signal handler. I'm wondering if it wouldn't be worth simply providing an API to handle signal in the way I describe and document that this is the recommended way to handle signals in multi-threaded applications. |
Comment author: @mshinwell I also wondered whether this should be thought about in the context as to how the multicore branch is going to handle things like this. |
Comment author: @jhjourdan Fixed in #2104 |
Original bug ID: 4127
Reporter: Claudio Sacerdoti Coen
Assigned to: @jhjourdan
Status: resolved (set by @jhjourdan on 2018-12-19T14:09:49Z)
Resolution: fixed
Priority: normal
Severity: major
Version: 3.09.2
Target version: later
Fixed in version: 4.08.0+dev/beta1/beta2
Category: threads
Has duplicate: #7709
Monitored by: enrico @gasche "Claudio Sacerdoti Coen"
Bug description
Thread.sigmask seems to be ignored.
I attach an ocaml program and the "equivalent" C code.
The two programs set a signal handler for SIGINT and then create two more
threads. Each thread uses sigmask to block SIGINT. SIGINT should now be received
only from the parent thread. In Ocaml any thread can still receive the SIGINT,
as if Thread.sigmask behaves as the identity function.
File attachments
The text was updated successfully, but these errors were encountered: