diff options
author | Richard Braun <rbraun@sceen.net> | 2020-12-21 02:10:16 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-12-21 02:10:16 +0100 |
commit | 5c06743c8a6f2184fbd3792b13dffa30f473b7b7 (patch) | |
tree | 07a16aeb17241b84b149ea13a19861f214b945b1 /hurd/hurd | |
parent | 53432762ac2ff24794089e2c767b976e54c2dc0a (diff) | |
download | glibc-5c06743c8a6f2184fbd3792b13dffa30f473b7b7.tar.gz glibc-5c06743c8a6f2184fbd3792b13dffa30f473b7b7.tar.xz glibc-5c06743c8a6f2184fbd3792b13dffa30f473b7b7.zip |
Hurd: make sigstates hold a reference on thread ports
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.
Diffstat (limited to 'hurd/hurd')
-rw-r--r-- | hurd/hurd/signal.h | 19 |
1 files changed, 15 insertions, 4 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)) |