]> granicus.if.org Git - python/commitdiff
Add SF patch #468347 -- mask signals for non-main pthreads, by Jason Lowe:
authorGuido van Rossum <guido@python.org>
Fri, 12 Oct 2001 21:49:17 +0000 (21:49 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 12 Oct 2001 21:49:17 +0000 (21:49 +0000)
   This patch updates Python/thread_pthread.h to mask all
   signals for any thread created. This will keep all
   signals masked for any thread that isn't the initial
   thread. For Solaris and Linux, the two platforms I was
   able to test it on, it solves bug #465673 (pthreads
   need signal protection) and probably will solve bug
   #219772 (Interactive InterPreter+ Thread -> core dump
   at exit).

   I'd be great if this could get some testing on other
   platforms, especially HP-UX pre 11.00 and post 11.00,
   as I had to make some guesses for the DCE thread case.
   AIX is also a concern as I saw some mention of using
   sigthreadmask() as a pthread_sigmask() equivalent, but
   this patch doesn't use sigthreadmask(). I don't have
   access to AIX.

Python/thread_pthread.h

index 26120d6886dac785964ade34c7a8f8b7560c0ca3..2592d39d5c1aa1811ca7bf92027669e26bbf5579 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pthread.h>
+#include <signal.h>
 
 
 /* try to determine what version of the Pthread Standard is installed.
 #endif
 
 
+/* On platforms that don't use standard POSIX threads pthread_sigmask()
+ * isn't present.  DEC threads uses sigprocmask() instead as do most
+ * other UNIX International compliant systems that don't have the full
+ * pthread implementation.
+ */
+#ifdef PY_PTHREAD_STD
+#  define SET_THREAD_SIGMASK pthread_sigmask
+#else
+#  define SET_THREAD_SIGMASK sigprocmask
+#endif
+
+
 /* A pthread mutex isn't sufficient to model the Python lock type
  * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
  * following are undefined:
@@ -135,6 +148,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
 {
        pthread_t th;
        int success;
+       sigset_t oldmask, newmask;
 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
        pthread_attr_t attrs;
 #endif
@@ -151,6 +165,14 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
 #ifdef PTHREAD_SYSTEM_SCHED_SUPPORTED
         pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
 #endif
+
+       /* Mask all signals in the current thread before creating the new
+        * thread.  This causes the new thread to start with all signals
+        * blocked.
+        */
+       sigfillset(&newmask);
+       SET_THREAD_SIGMASK(SIG_BLOCK, &newmask, &oldmask);
+
        success = pthread_create(&th, 
 #if defined(PY_PTHREAD_D4)
                                 pthread_attr_default,
@@ -174,6 +196,10 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
                                 (void *)arg
 #endif
                                 );
+
+       /* Restore signal mask for original thread */
+       SET_THREAD_SIGMASK(SIG_SETMASK, &oldmask, NULL);
+
 #ifdef THREAD_STACK_SIZE
        pthread_attr_destroy(&attrs);
 #endif