Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0004127OCamlotherlibspublic2006-10-02 16:012017-03-10 18:27
ReporterClaudio Sacerdoti Coen 
Assigned Todim 
PrioritynormalSeveritymajorReproducibilityalways
StatusassignedResolutionopen 
PlatformOSOS Version
Product Version3.09.2 
Target VersionlaterFixed in Version 
Summary0004127: Thread.sigmask not working under pthreads
DescriptionThread.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.
TagsNo tags attached.
Attached Filesc file icon thread_mask.c [^] (636 bytes) 2006-10-02 16:01 [Show Content]
? file icon a.ml [^] (867 bytes) 2006-10-02 16:02 [Show Content]

- Relationships

-  Notes
(0003932)
xleroy (administrator)
2007-02-22 11:12

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.
(0006351)
xleroy (administrator)
2011-12-17 09:49

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.
(0017622)
shinwell (developer)
2017-03-10 17:53

Jeremie has been kindly volunteered to think about this.
(0017624)
dim (developer)
2017-03-10 18:19

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 () =
  init_signal_manager_thread ();
  ignore (Thread.sigmask SIG_BLOCK sigs_i_am_interested_in : int list);
  while true do
    let signo = Thread.wait_signal sigs_i_am_interested_in in
    process_signal signo
  done
;;

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()
{
  signal_manager_thread = pthread_self();
  return Val_unit;
}

static void handle_signal(int signum)
{
  if (!pthread_equal(pthread_self(), signal_manager_thread))
    pthread_kill(signal_manager_thread, 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.
(0017625)
shinwell (developer)
2017-03-10 18:27

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.

- Issue History
Date Modified Username Field Change
2006-10-02 16:01 Claudio Sacerdoti Coen New Issue
2006-10-02 16:01 Claudio Sacerdoti Coen File Added: thread_mask.c
2006-10-02 16:02 Claudio Sacerdoti Coen File Added: a.ml
2006-11-15 16:13 doligez Status new => acknowledged
2007-02-22 11:12 xleroy Note Added: 0003932
2007-02-22 11:12 xleroy Assigned To => xleroy
2007-02-22 11:12 xleroy Status acknowledged => confirmed
2011-12-17 09:49 xleroy Note Added: 0006351
2011-12-17 09:49 xleroy Assigned To xleroy =>
2012-07-06 16:41 doligez Target Version => 4.01.0+dev
2012-07-31 13:37 doligez Target Version 4.01.0+dev => 4.00.1+dev
2012-09-06 19:23 frisch Target Version 4.00.1+dev => later
2016-12-07 17:01 shinwell Category OCaml general => OCaml otherlibs
2017-02-23 16:42 doligez Category OCaml otherlibs => otherlibs
2017-03-10 17:53 shinwell Note Added: 0017622
2017-03-10 17:53 shinwell Assigned To => dim
2017-03-10 17:53 shinwell Status confirmed => assigned
2017-03-10 18:19 dim Note Added: 0017624
2017-03-10 18:27 shinwell Note Added: 0017625


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker