summaryrefslogtreecommitdiffstats
path: root/lib/libthr
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2012-01-21 18:06:18 +0000
committerkib <kib@FreeBSD.org>2012-01-21 18:06:18 +0000
commitfc150a4b545266cc140f4994f5ee35dc631b8fbf (patch)
treedcea9c724b5ceeb7137ba5c561bdea94e95b3144 /lib/libthr
parent8c121450bcfa7aaf7c661baf2809bafc48c1f60f (diff)
downloadFreeBSD-src-fc150a4b545266cc140f4994f5ee35dc631b8fbf.zip
FreeBSD-src-fc150a4b545266cc140f4994f5ee35dc631b8fbf.tar.gz
Use getcontextx(3) internal API instead of getcontext(2) to provide
the signal handlers with the context information in the deferrred case. Only enable the use of getcontextx(3) in the deferred signal delivery code on amd64 and i386. Sparc64 seems to have some undetermined issues with interaction of alloca(3) and signal delivery. Tested by: flo (who also provided sparc64 harware access for me), pho Discussed with: marius MFC after: 1 month
Diffstat (limited to 'lib/libthr')
-rw-r--r--lib/libthr/thread/thr_sig.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c
index 66358db..46cbd82 100644
--- a/lib/libthr/thread/thr_sig.c
+++ b/lib/libthr/thread/thr_sig.c
@@ -32,6 +32,7 @@
#include <sys/signalvar.h>
#include <signal.h>
#include <errno.h>
+#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "un-namespace.h"
@@ -314,16 +315,24 @@ check_cancel(struct pthread *curthread, ucontext_t *ucp)
static void
check_deferred_signal(struct pthread *curthread)
{
- ucontext_t uc;
+ ucontext_t *uc;
struct sigaction act;
siginfo_t info;
if (__predict_true(curthread->deferred_siginfo.si_signo == 0))
return;
- getcontext(&uc);
+
+#if defined(__amd64__) || defined(__i386__)
+ uc = alloca(__getcontextx_size());
+ __fillcontextx((char *)uc);
+#else
+ ucontext_t ucv;
+ uc = &ucv;
+ getcontext(uc);
+#endif
if (curthread->deferred_siginfo.si_signo != 0) {
act = curthread->deferred_sigact;
- uc.uc_sigmask = curthread->deferred_sigmask;
+ uc->uc_sigmask = curthread->deferred_sigmask;
memcpy(&info, &curthread->deferred_siginfo, sizeof(siginfo_t));
/* remove signal */
curthread->deferred_siginfo.si_signo = 0;
@@ -334,7 +343,7 @@ check_deferred_signal(struct pthread *curthread)
tact.sa_handler = SIG_DFL;
_sigaction(info.si_signo, &tact, NULL);
}
- handle_signal(&act, info.si_signo, &info, &uc);
+ handle_signal(&act, info.si_signo, &info, uc);
}
}
OpenPOWER on IntegriCloud