public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] nptl: Provide a way to block all signals for the timer helper thread
@ 2020-05-12 15:02 Florian Weimer
  2020-05-12 15:03 ` Florian Weimer
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Florian Weimer @ 2020-05-12 15:02 UTC (permalink / raw)
  To: libc-alpha

timer_create needs to create threads with all signals blocked,
including SIGTIMER (which happens to equal SIGCANCEL).  Add a new
internal interface which provides an explicit way to achieve that.

Fixes commit b3cae39dcbfa2432b3f3aa28854d8ac57f0de1b8 ("nptl: Start
new threads with all signals blocked [BZ #25098]").

Tested on x86_64-linux-gnu.

-----
 nptl/Versions                            |  1 +
 nptl/pthreadP.h                          | 10 +++++++++
 nptl/pthread_create.c                    | 36 +++++++++++++++++++++++---------
 sysdeps/unix/sysv/linux/timer_routines.c | 16 ++++++--------
 4 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/nptl/Versions b/nptl/Versions
index f7140277f5..17a711dfb1 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -285,5 +285,6 @@ libpthread {
     __pthread_barrier_init; __pthread_barrier_wait;
     __shm_directory;
     __libpthread_freeres;
+    __pthread_create_internal;
   }
 }
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index c4e72f57a9..4e065ace58 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -339,6 +339,16 @@ extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
 hidden_proto (__pthread_cleanup_upto)
 #endif
 
+/* Exactly like pthread_create if NEW_SIGMASK == NULL.  Otherwise, do
+   not use the current signal mask for the new thread, but set it to
+   *NEW_SIGMASK instead (without unblocking internal signals).  */
+extern int __pthread_create_internal (pthread_t *newthread,
+				      const pthread_attr_t *attr,
+				      void *(*start_routine) (void *),
+				      void *arg, const sigset_t *new_sigmask);
+#if IS_IN (libpthread)
+hidden_proto (__pthread_create_internal)
+#endif
 
 /* Functions with versioned interfaces.  */
 extern int __pthread_create_2_1 (pthread_t *newthread,
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index afd379e89a..2430d65723 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -603,10 +603,10 @@ report_thread_creation (struct pthread *pd)
   return false;
 }
 
-
 int
-__pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
-		      void *(*start_routine) (void *), void *arg)
+__pthread_create_internal (pthread_t *newthread, const pthread_attr_t *attr,
+			   void *(*start_routine) (void *), void *arg,
+			   const sigset_t *new_sigmask)
 {
   STACK_VARIABLES;
 
@@ -762,14 +762,21 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
   sigset_t original_sigmask;
   __libc_signal_block_all (&original_sigmask);
 
-  /* Conceptually, the new thread needs to inherit the signal mask of
-     this thread.  Therefore, it needs to restore the saved signal
-     mask of this thread, so save it in the startup information.  */
-  pd->sigmask = original_sigmask;
+  if (new_sigmask != NULL)
+    /* The caller supplied the signal mask for the new thread.  */
+    pd->sigmask = *new_sigmask;
+  else
+    {
+      /* Conceptually, the new thread needs to inherit the signal mask
+	 of this thread.  Therefore, it needs to restore the saved
+	 signal mask of this thread, so save it in the startup
+	 information.  */
+      pd->sigmask = original_sigmask;
 
-  /* Reset the cancellation signal mask in case this thread is running
-     cancellation.  */
-  __sigdelset (&pd->sigmask, SIGCANCEL);
+      /* Reset the cancellation signal mask in case this thread is
+	 running cancellation.  */
+      __sigdelset (&pd->sigmask, SIGCANCEL);
+    }
 
   /* Start the thread.  */
   if (__glibc_unlikely (report_thread_creation (pd)))
@@ -873,6 +880,15 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
 
   return retval;
 }
+hidden_def (__pthread_create_internal)
+
+int
+__pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
+		      void *(*start_routine) (void *), void *arg)
+{
+  return __pthread_create_internal (newthread, attr, start_routine, arg,
+				    false);
+}
 versioned_symbol (libpthread, __pthread_create_2_1, pthread_create, GLIBC_2_1);
 
 
diff --git a/sysdeps/unix/sysv/linux/timer_routines.c b/sysdeps/unix/sysv/linux/timer_routines.c
index 63083f6f91..7a5fa3dbb2 100644
--- a/sysdeps/unix/sysv/linux/timer_routines.c
+++ b/sysdeps/unix/sysv/linux/timer_routines.c
@@ -136,23 +136,19 @@ __start_helper_thread (void)
   (void) pthread_attr_init (&attr);
   (void) pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr));
 
-  /* Block all signals in the helper thread but SIGSETXID.  To do this
-     thoroughly we temporarily have to block all signals here.  The
-     helper can lose wakeups if SIGTIMER is not blocked throughout.  */
-  sigset_t ss;
-  __libc_signal_block_app (&ss);
-  __libc_signal_block_sigtimer (NULL);
+  /* Block all signals in the helper thread but SIGSETXID.  */
+  sigset_t new_sigmask;
+  __sigfillset (&new_sigmask);
+  __sigdelset (&new_sigmask, SIGSETXID);
 
   /* Create the helper thread for this timer.  */
   pthread_t th;
-  int res = pthread_create (&th, &attr, timer_helper_thread, NULL);
+  int res = __pthread_create_internal (&th, &attr, timer_helper_thread, NULL,
+				       &new_sigmask);
   if (res == 0)
     /* We managed to start the helper thread.  */
     __helper_tid = ((struct pthread *) th)->tid;
 
-  /* Restore the signal mask.  */
-  __libc_signal_restore_set (&ss);
-
   /* No need for the attribute anymore.  */
   (void) pthread_attr_destroy (&attr);
 


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-05-19 11:09 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-12 15:02 [PATCH] nptl: Provide a way to block all signals for the timer helper thread Florian Weimer
2020-05-12 15:03 ` Florian Weimer
2020-05-12 16:09   ` H.J. Lu
2020-05-12 18:38     ` Carlos O'Donell
2020-05-12 19:02 ` Adhemerval Zanella
2020-05-14 15:46   ` Florian Weimer
2020-05-14 17:54     ` Carlos O'Donell
2020-05-12 19:09 ` Carlos O'Donell
2020-05-12 19:17   ` Florian Weimer
2020-05-14 17:52     ` Carlos O'Donell
2020-05-14 18:30       ` Florian Weimer
2020-05-14 19:33         ` Carlos O'Donell
2020-05-14 20:32           ` Adhemerval Zanella
2020-05-14 20:40             ` Carlos O'Donell
2020-05-19 11:08           ` Florian Weimer
2020-05-13 15:25 ` Carlos O'Donell
2020-05-13 16:22   ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).