From patchwork Mon Dec 21 02:38:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 41493 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3C5A73857830; Mon, 21 Dec 2020 02:38:49 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from hera.aquilenet.fr (hera.aquilenet.fr [IPv6:2a0c:e300::1]) by sourceware.org (Postfix) with ESMTPS id 3E8B03857812 for ; Mon, 21 Dec 2020 02:38:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3E8B03857812 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ens-lyon.org Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=samuel.thibault@ens-lyon.org Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 57B0EB06; Mon, 21 Dec 2020 03:38:45 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at aquilenet.fr Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3R0jvgqb-Zb1; Mon, 21 Dec 2020 03:38:43 +0100 (CET) Received: from function.youpi.perso.aquilenet.fr (lfbn-bor-1-56-204.w90-50.abo.wanadoo.fr [90.50.148.204]) by hera.aquilenet.fr (Postfix) with ESMTPSA id AFC7DB94; Mon, 21 Dec 2020 03:38:43 +0100 (CET) Received: from samy by function.youpi.perso.aquilenet.fr with local (Exim 4.94) (envelope-from ) id 1krB5u-00GGGy-Kw; Mon, 21 Dec 2020 03:38:42 +0100 From: Samuel Thibault To: libc-alpha@sourceware.org Subject: [hurd, commited] Hurd: make sigstates hold a reference on thread ports Date: Mon, 21 Dec 2020 03:38:40 +0100 Message-Id: <20201221023840.3875757-1-samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_NEUTRAL, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: commit-hurd@gnu.org, Richard Braun Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" From: Richard Braun This change is required in order to correctly release per-thread resources. Directly reusing the threading library reference isn't possible since the sigstate is also used early in the main thread, before threading is initialized. * hurd/hurd/signal.h (_hurd_self_sigstate): Drop thread reference after calling _hurd_thread_sigstate. (_hurd_critical_section_lock): Likewise. * hurd/hurdsig.c (_hurd_thread_sigstate): Add a reference on the thread. (_hurd_sigstate_delete): Drop thread reference. --- hurd/hurd/signal.h | 19 +++++++++++++++---- hurd/hurdsig.c | 17 ++++++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h index f6f91218db..2a0aa20b72 100644 --- a/hurd/hurd/signal.h +++ b/hurd/hurd/signal.h @@ -67,7 +67,9 @@ struct hurd_sigstate spin_lock_t lock; /* Locks most of the rest of the structure. */ + /* The signal state holds a reference on the thread port. */ thread_t thread; + struct hurd_sigstate *next; /* Linked-list of thread sigstates. */ sigset_t blocked; /* What signals are blocked. */ @@ -119,7 +121,9 @@ struct hurd_sigstate extern struct hurd_sigstate *_hurd_sigstates; -/* Get the sigstate of a given thread, taking its lock. */ +/* Get the sigstate of a given thread. If there was no sigstate for + the thread, one is created, and the thread gains a reference. If + the given thread is MACH_PORT_NULL, return the global sigstate. */ extern struct hurd_sigstate *_hurd_thread_sigstate (thread_t); @@ -162,7 +166,11 @@ _HURD_SIGNAL_H_EXTERN_INLINE struct hurd_sigstate * _hurd_self_sigstate (void) { if (THREAD_GETMEM (THREAD_SELF, _hurd_sigstate) == NULL) - THREAD_SETMEM (THREAD_SELF, _hurd_sigstate, _hurd_thread_sigstate (__mach_thread_self ())); + { + thread_t self = __mach_thread_self (); + THREAD_SETMEM (THREAD_SELF, _hurd_sigstate, _hurd_thread_sigstate (self)); + __mach_port_deallocate (__mach_task_self (), self); + } return THREAD_GETMEM (THREAD_SELF, _hurd_sigstate); } # endif @@ -210,12 +218,15 @@ _hurd_critical_section_lock (void) ss = THREAD_GETMEM (THREAD_SELF, _hurd_sigstate); if (ss == NULL) { + thread_t self = __mach_thread_self (); + /* The thread variable is unset; this must be the first time we've asked for it. In this case, the critical section flag cannot possible already be set. Look up our sigstate structure the slow way. */ - ss = _hurd_thread_sigstate (__mach_thread_self ()); - THREAD_SETMEM(THREAD_SELF, _hurd_sigstate, ss); + ss = _hurd_thread_sigstate (self); + THREAD_SETMEM (THREAD_SELF, _hurd_sigstate, ss); + __mach_port_deallocate (__mach_task_self (), self); } if (! __spin_try_lock (&ss->critical_section_lock)) diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c index 852ae7e441..6fdbf383ee 100644 --- a/hurd/hurdsig.c +++ b/hurd/hurdsig.c @@ -114,6 +114,8 @@ _hurd_thread_sigstate (thread_t thread) } else { + error_t err; + /* Use the global actions as a default for new threads. */ struct hurd_sigstate *s = _hurd_global_sigstate; if (s) @@ -127,6 +129,11 @@ _hurd_thread_sigstate (thread_t thread) ss->next = _hurd_sigstates; _hurd_sigstates = ss; + + err = __mach_port_mod_refs (__mach_task_self (), thread, + MACH_PORT_RIGHT_SEND, 1); + if (err) + __libc_fatal ("hurd: Can't add reference on Mach thread\n"); } } __mutex_unlock (&_hurd_siglock); @@ -135,8 +142,7 @@ _hurd_thread_sigstate (thread_t thread) libc_hidden_def (_hurd_thread_sigstate) /* Destroy a sigstate structure. Called by libpthread just before the - * corresponding thread is terminated (the kernel thread port must remain valid - * until this function is called.) */ + * corresponding thread is terminated. */ void _hurd_sigstate_delete (thread_t thread) { @@ -153,7 +159,12 @@ _hurd_sigstate_delete (thread_t thread) __mutex_unlock (&_hurd_siglock); if (ss) - free (ss); + { + if (ss->thread != MACH_PORT_NULL) + __mach_port_deallocate (__mach_task_self (), ss->thread); + + free (ss); + } } /* Make SS a global receiver, with pthread signal semantics. */