Subject: Re: better signal delivery to threads
To: Nathan J. Williams <>
From: Matthias Drochner <>
List: tech-kern
Date: 08/23/2005 13:46:49
This is a multipart MIME message.

Content-Type: text/plain; charset=us-ascii said:
> As currently specified, the implementation is permitted to pick any
> thread where the signal is unblocked or that is calling sigwait() for
> the relevant signal. 

I know... so I've checked how other systems behave:
DEC OSF1 and Solaris both consistently wake up the main thread,
even if it is blocked in I/O.
Linux wakes up the main thread if in sleep(); if blocked in read()
a random child thread is chosen.
None of these systems wake up more than one thread, so I won't
pursue further what I wrote in the second half of my last mail.

The appended patch models the OSF1/Solaris behaviour -- somehow
I like that most. My tests were successful so far. said:
> did you try to report this to the Python mailing list?

I'm in doubt they will care about Problems with non-mainstream
operating systems. I've reported some 64-bit lossage once, even
that was never fixed. (The affected interface is declared obsolete,
but old scripts will still fail.)

> why patch kernel if the SW running on it is broken?

If broken, then broken by design. I don't see how the Python
interpreter could do something about this. There are independant
scripts which don't coordinate their signal masks.
Arguably, the signal handling interface shouldn't be exposed
to user scripts, but it was there before thread support.
Modern languages which are higher abstraced and thread-centric
from the beginning probably don't have this problem.

> I'm pretty, although not 100%, sure that NetBSD is _not_ at fault
> here

As said, NetBSD is technically correct. But if a program works
on other systems but not on NetBSD, NetBSD will be blamed.

best regards

Content-Type: text/plain ; name="thrsel.txt"; charset=us-ascii
Content-Description: thrsel.txt
Content-Disposition: attachment; filename="thrsel.txt"

Index: pthread_sig.c
RCS file: /cvsroot/src/lib/libpthread/pthread_sig.c,v
retrieving revision 1.41
diff -u -p -r1.41 pthread_sig.c
--- pthread_sig.c	26 Jul 2005 20:16:07 -0000	1.41
+++ pthread_sig.c	23 Aug 2005 11:11:02 -0000
@@ -117,6 +117,8 @@ __strong_alias(__libc_thr_sigsetmask,pth
+static pthread_t mainthread;
@@ -125,6 +127,8 @@ pthread__signal_init(void)
+	mainthread = pthread__self();
@@ -692,10 +696,18 @@ pthread__signal(pthread_t self, pthread_
 				self, target, target->pt_state, target->pt_sigmask.__bits[0]));
 			if (!__sigismember14(&target->pt_sigmask,
 			    si->si_signo)) {
-				if (target->pt_blockgen == target->pt_unblockgen) {
+				if (target == mainthread) {
+					if (good)
+						pthread_spinunlock(self, &good->pt_siglock);
 					good = target;
 					/* Leave target locked */
+				} else if (target->pt_blockgen == target->pt_unblockgen) {
+					if (good == NULL) {
+						good = target;
+						/* Leave target locked */
+						continue;
+					}
 				} else if (okay == NULL) {
 					okay = target;
 					/* Leave target locked */