[PATCH v2] linux: Do not spawn a new thread for SIGEV_THREAD (BZ 30558, 27895, 29705, 32833)

Florian Weimer fweimer@redhat.com
Mon Apr 7 07:47:36 GMT 2025


* Adhemerval Zanella:

> +/* Reset internal thread state if the callback issues pthread_exit.  It avoids
> +   recreating the thread and having possible unreported missed events due
> +   thread creation failure.  */
> +static void
> +timer_helper_thread_cleanup (void *arg)
> +{
> +  struct pthread *self = THREAD_SELF;
> +
> +  /* Call destructors for the thread_local TLS variables.  */
> +  call_function_static_weak (__call_tls_dtors);
> +
> +  /* Run the destructor for the thread-local data.  */
> +  __nptl_deallocate_tsd ();
> +
> +  /* Clean up any state libc stored in thread-local variables.  */
> +  __libc_thread_freeres ();
> +
> +  /* Reset internal TCB state.  */
> +  struct cleanup_args_t *args = arg;
> +  self->cleanup_jmp_buf = args->cleanup_jmp_buf;
> +  self->cleanup_jmp_buf->priv.data.prev = NULL;
> +  self->cleanup_jmp_buf->priv.data.cleanup = NULL;
> +  self->cleanup_jmp_buf->priv.data.canceltype = 0;
> +  self->cleanup = NULL;
> +  self->exc = (struct _Unwind_Exception) { 0 };
> +  self->cancelhandling = 0;
> +  self->nextevent = NULL;
> +
> +  /* Re-initialize the TLS.  */
> +  _dl_allocate_tls_init (TLS_TPADJ (self), true);
> +
> +  /* Reset to the expected initial signal mask.  */
> +  internal_sigset_t ss;
> +  internal_sigfillset (&ss);
> +  internal_sigdelset (&ss, SIGSETXID);
> +  internal_sigprocmask (SIG_SETMASK, &ss, NULL);
> +
> +  /* There is no need to perform any additional cleanup by the frames.  */
> +  struct __jmp_buf_tag *env = args->jb;
> +  __longjmp (env[0].__jmpbuf, 1);
> +}
> +
> +static void *
> +timer_helper_thread (void *arg)
> +{
> +  struct pthread *self = THREAD_SELF;
> +  struct timer_helper_thread_args_t *args = arg;
> +  struct cleanup_args_t clargs = {
> +    .cleanup_jmp_buf = self->cleanup_jmp_buf
> +  };

It might be moore maintainable to integrate this special handling into
start_thread in nptl/pthread_create.c.  Otherwise, this looks like lots
of layering violations to me (access to cancellation internals from the
outside of the cancellation subsystem).

Thanks,
Florian



More information about the Libc-alpha mailing list