summaryrefslogtreecommitdiff
path: root/hurd/hurdsig.c
diff options
context:
space:
mode:
Diffstat (limited to 'hurd/hurdsig.c')
-rw-r--r--hurd/hurdsig.c96
1 files changed, 79 insertions, 17 deletions
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index 528343997e..7c1b976220 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -20,9 +20,10 @@
#include <string.h>
#include <cthreads.h> /* For `struct mutex'. */
-#include <pthread.h>
+#include <pthreadP.h>
#include <mach.h>
#include <mach/thread_switch.h>
+#include <mach/mig_support.h>
#include <hurd.h>
#include <hurd/id.h>
@@ -32,6 +33,8 @@
#include "hurdmalloc.h" /* XXX */
#include "../locale/localeinfo.h"
+#include <libc-diag.h>
+
const char *_hurdsig_getenv (const char *);
struct mutex _hurd_siglock;
@@ -123,6 +126,7 @@ _hurd_thread_sigstate (thread_t thread)
__mutex_unlock (&_hurd_siglock);
return ss;
}
+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
@@ -216,7 +220,6 @@ _hurd_sigstate_actions (struct hurd_sigstate *ss)
else
return ss->actions;
}
-
/* Signal delivery itself is on this page. */
@@ -343,8 +346,14 @@ interrupted_reply_port_location (thread_t thread,
/* Faulted trying to read the TCB. */
return NULL;
+ DIAG_PUSH_NEEDS_COMMENT;
+ /* GCC 6 and before seem to be confused by the setjmp call inside
+ _hurdsig_catch_memory_fault and think that we may be returning a second
+ time to here with portloc uninitialized (but we never do). */
+ DIAG_IGNORE_NEEDS_COMMENT (6, "-Wmaybe-uninitialized");
/* Fault now if this pointer is bogus. */
*(volatile mach_port_t *) portloc = *portloc;
+ DIAG_POP_NEEDS_COMMENT;
if (sigthread)
_hurdsig_end_catch_fault ();
@@ -1162,6 +1171,7 @@ post_pending (struct hurd_sigstate *ss, sigset_t pending, void (*reply) (void))
return 1;
}
+<<<<<<< HEAD
/* Post all the pending signals of all threads and return 1. If a traced
signal is encountered, abort immediately and return 0. */
static int
@@ -1218,6 +1228,57 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
ss = post_signal (ss, signo, detail, untraced, reply);
if (! ss)
return;
+=======
+ /* No pending signals left undelivered for this thread.
+ If we were sent signal 0, we need to check for pending
+ signals for all threads. */
+ if (signo == 0)
+ {
+ __spin_unlock (&ss->lock);
+ __mutex_lock (&_hurd_siglock);
+ for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
+ {
+ __spin_lock (&ss->lock);
+ for (signo = 1; signo < NSIG; ++signo)
+ if (__sigismember (&ss->pending, signo)
+ && (!__sigismember (&ss->blocked, signo)
+ /* We "deliver" immediately pending blocked signals whose
+ action might be to ignore, so that if ignored they are
+ dropped right away. */
+ || ss->actions[signo].sa_handler == SIG_IGN
+ || ss->actions[signo].sa_handler == SIG_DFL))
+ {
+ __mutex_unlock (&_hurd_siglock);
+ goto deliver_pending;
+ }
+ __spin_unlock (&ss->lock);
+ }
+ __mutex_unlock (&_hurd_siglock);
+ }
+ else
+ {
+ /* No more signals pending; SS->lock is still locked.
+ Wake up any sigsuspend call that is blocking SS->thread. */
+ if (ss->suspended != MACH_PORT_NULL)
+ {
+ /* There is a sigsuspend waiting. Tell it to wake up. */
+ error_t err;
+ mach_msg_header_t msg;
+ msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
+ msg.msgh_remote_port = ss->suspended;
+ msg.msgh_local_port = MACH_PORT_NULL;
+ /* These values do not matter. */
+ msg.msgh_id = 8675309; /* Jenny, Jenny. */
+ ss->suspended = MACH_PORT_NULL;
+ err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0,
+ MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
+ MACH_PORT_NULL);
+ assert_perror (err);
+ }
+ __spin_unlock (&ss->lock);
+ }
+ }
+>>>>>>> t/tls-threadvar
/* The signal was neither fatal nor traced. We still hold SS->lock. */
if (signo != 0 && ss->thread != MACH_PORT_NULL)
@@ -1456,11 +1517,8 @@ _hurdsig_init (const int *intarray, size_t intarraysize)
/* Start the signal thread listening on the message port. */
-#pragma weak cthread_fork
-#pragma weak cthread_detach
-#pragma weak pthread_getattr_np
-#pragma weak pthread_attr_getstack
- if (!cthread_fork)
+#pragma weak __cthread_fork
+ if (!__cthread_fork)
{
err = __thread_create (__mach_task_self (), &_hurd_msgport_thread);
assert_perror (err);
@@ -1485,7 +1543,6 @@ _hurdsig_init (const int *intarray, size_t intarraysize)
}
else
{
- cthread_t thread;
/* When cthreads is being used, we need to make the signal thread a
proper cthread. Otherwise it cannot use mutex_lock et al, which
will be the cthreads versions. Various of the message port RPC
@@ -1495,17 +1552,22 @@ _hurdsig_init (const int *intarray, size_t intarraysize)
we'll let the signal thread's per-thread variables be found as for
any normal cthread, and just leave the magic __hurd_sigthread_*
values all zero so they'll be ignored. */
- cthread_detach (thread = cthread_fork ((cthread_fn_t) &_hurd_msgport_receive, 0));
-
- if (pthread_getattr_np)
+#pragma weak __cthread_detach
+#pragma weak __pthread_getattr_np
+#pragma weak __pthread_attr_getstack
+ __cthread_t thread = __cthread_fork (
+ (cthread_fn_t) &_hurd_msgport_receive, 0);
+ __cthread_detach (thread);
+
+ if (__pthread_getattr_np)
{
- /* Record stack layout for fork() */
+ /* Record signal thread stack layout for fork() */
pthread_attr_t attr;
void *addr;
size_t size;
- pthread_getattr_np ((pthread_t) thread, &attr);
- pthread_attr_getstack (&attr, &addr, &size);
+ __pthread_getattr_np ((pthread_t) thread, &attr);
+ __pthread_attr_getstack (&attr, &addr, &size);
__hurd_sigthread_stack_base = (uintptr_t) addr;
__hurd_sigthread_stack_end = __hurd_sigthread_stack_base + size;
}
@@ -1561,14 +1623,14 @@ reauth_proc (mach_port_t new)
__mach_port_destroy (__mach_task_self (), ref);
/* Set the owner of the process here too. */
- mutex_lock (&_hurd_id.lock);
+ __mutex_lock (&_hurd_id.lock);
if (!_hurd_check_ids ())
HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
__proc_setowner (port,
(_hurd_id.gen.nuids
? _hurd_id.gen.uids[0] : 0),
!_hurd_id.gen.nuids));
- mutex_unlock (&_hurd_id.lock);
+ __mutex_unlock (&_hurd_id.lock);
(void) &reauth_proc; /* Silence compiler warning. */
}