summaryrefslogtreecommitdiff
path: root/hurd/hurd/signal.h
diff options
context:
space:
mode:
Diffstat (limited to 'hurd/hurd/signal.h')
-rw-r--r--hurd/hurd/signal.h38
1 files changed, 16 insertions, 22 deletions
diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
index 1973bcdb3c..fdaafdf459 100644
--- a/hurd/hurd/signal.h
+++ b/hurd/hurd/signal.h
@@ -47,9 +47,9 @@ struct hurd_signal_preempter; /* <hurd/sigpreempt.h> */
struct hurd_sigstate
{
- spin_lock_t lock; /* Locks most of the rest of the structure. */
+ spin_lock_t critical_section_lock; /* Held if in critical section. */
- int critical_section; /* Nonzero if in critical section. */
+ spin_lock_t lock; /* Locks most of the rest of the structure. */
thread_t thread;
struct hurd_sigstate *next; /* Linked-list of thread sigstates. */
@@ -159,27 +159,22 @@ _hurd_critical_section_lock (void)
(void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE);
struct hurd_sigstate *ss = *location;
if (ss == NULL)
- /* 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; this locks the sigstate lock. */
- ss = *location = _hurd_thread_sigstate (__mach_thread_self ());
- else
- __spin_lock (&ss->lock);
-
- if (ss->critical_section)
{
- /* We are already in a critical section, so do nothing. */
+ /* 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; this locks the sigstate lock. */
+ ss = *location = _hurd_thread_sigstate (__mach_thread_self ());
__spin_unlock (&ss->lock);
- return NULL;
}
- /* Set the critical section flag so no signal handler will run. */
- ss->critical_section = 1;
- __spin_unlock (&ss->lock);
+ if (! __spin_try_lock (&ss->critical_section_lock))
+ /* We are already in a critical section, so do nothing. */
+ return NULL;
- /* Return our sigstate pointer; this will be passed to
- _hurd_critical_section_unlock to clear the critical section flag. */
+ /* With the critical section lock held no signal handler will run.
+ Return our sigstate pointer; this will be passed to
+ _hurd_critical_section_unlock to unlock it. */
return ss;
}
@@ -191,19 +186,18 @@ _hurd_critical_section_unlock (void *our_lock)
return;
else
{
- /* It was us who acquired the critical section lock. Clear the
- critical section flag. */
+ /* It was us who acquired the critical section lock. Unlock it. */
struct hurd_sigstate *ss = our_lock;
sigset_t pending;
__spin_lock (&ss->lock);
- ss->critical_section = 0;
+ __spin_unlock (&ss->critical_section_lock);
pending = ss->pending & ~ss->blocked;
__spin_unlock (&ss->lock);
if (pending)
/* There are unblocked signals pending, which weren't
delivered because we were in the critical section.
Tell the signal thread to deliver them now. */
- __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
}
}