diff options
Diffstat (limited to 'hurd/hurd/signal.h')
-rw-r--r-- | hurd/hurd/signal.h | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h index 796761eba4..8d63d2d0c0 100644 --- a/hurd/hurd/signal.h +++ b/hurd/hurd/signal.h @@ -40,7 +40,6 @@ #include <cthreads.h> /* For `struct mutex'. */ #include <setjmp.h> /* For `jmp_buf'. */ #include <spin-lock.h> -#include <hurd/threadvar.h> /* We cache sigstate in a threadvar. */ struct hurd_signal_preemptor; /* <hurd/sigpreempt.h> */ @@ -64,7 +63,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. */ @@ -118,7 +119,9 @@ extern struct hurd_sigstate *_hurd_sigstates; extern struct mutex _hurd_siglock; /* Locks _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); @@ -155,14 +158,17 @@ extern void _hurd_sigstate_delete (thread_t thread); #define _HURD_SIGNAL_H_EXTERN_INLINE __extern_inline #endif -#ifdef __USE_EXTERN_INLINES +#if defined __USE_EXTERN_INLINES && defined _LIBC && !defined NOT_IN_libc _HURD_SIGNAL_H_EXTERN_INLINE struct hurd_sigstate * _hurd_self_sigstate (void) { - struct hurd_sigstate **location = (struct hurd_sigstate **) - (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE); + struct hurd_sigstate **location = &THREAD_SELF->_hurd_sigstate; if (*location == NULL) - *location = _hurd_thread_sigstate (__mach_thread_self ()); + { + thread_t self = __mach_thread_self (); + *location = _hurd_thread_sigstate (self); + __mach_port_deallocate (__mach_task_self (), self); + } return *location; } #endif @@ -188,21 +194,37 @@ extern int _hurd_core_limit; void *_hurd_critical_section_lock (void); -#ifdef __USE_EXTERN_INLINES +#if defined __USE_EXTERN_INLINES && defined _LIBC && !defined NOT_IN_libc _HURD_SIGNAL_H_EXTERN_INLINE void * _hurd_critical_section_lock (void) { - struct hurd_sigstate **location = (struct hurd_sigstate **) - (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE); - struct hurd_sigstate *ss = *location; + struct hurd_sigstate **location; + struct hurd_sigstate *ss; + +#ifdef __LIBC_NO_TLS + if (__LIBC_NO_TLS()) + /* TLS is currently initializing, no need to enter critical section. */ + return NULL; +#endif + + location = &THREAD_SELF->_hurd_sigstate; + ss = *location; 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 +<<<<<<< HEAD + way. */ + ss = THREAD_SELF->_hurd_sigstate = _hurd_thread_sigstate (self); + __mach_port_deallocate (__mach_task_self (), self); +======= way; this locks the sigstate lock. */ ss = *location = _hurd_thread_sigstate (__mach_thread_self ()); __spin_unlock (&ss->lock); +>>>>>>> t/tls-threadvar } if (! __spin_try_lock (&ss->critical_section_lock)) @@ -218,7 +240,7 @@ _hurd_critical_section_lock (void) void _hurd_critical_section_unlock (void *our_lock); -#ifdef __USE_EXTERN_INLINES +#if defined __USE_EXTERN_INLINES && defined _LIBC && !defined NOT_IN_libc _HURD_SIGNAL_H_EXTERN_INLINE void _hurd_critical_section_unlock (void *our_lock) { |