svn commit: r211737 - in head/lib/libthr: . thread
David Xu
davidxu at FreeBSD.org
Tue Aug 24 09:57:07 UTC 2010
Author: davidxu
Date: Tue Aug 24 09:57:06 2010
New Revision: 211737
URL: http://svn.freebsd.org/changeset/base/211737
Log:
Add wrapper for setcontext() and swapcontext(), the wrappers
unblock SIGCANCEL which is needed by thread cancellation.
Modified:
head/lib/libthr/pthread.map
head/lib/libthr/thread/thr_private.h
head/lib/libthr/thread/thr_sig.c
Modified: head/lib/libthr/pthread.map
==============================================================================
--- head/lib/libthr/pthread.map Tue Aug 24 08:11:11 2010 (r211736)
+++ head/lib/libthr/pthread.map Tue Aug 24 09:57:06 2010 (r211737)
@@ -342,6 +342,7 @@ FBSDprivate_1.0 {
_pthread_timedjoin_np;
_pthread_yield;
_raise;
+ _setcontext;
_sigaction;
_sigprocmask;
_sigsuspend;
@@ -351,6 +352,7 @@ FBSDprivate_1.0 {
_spinlock;
_spinlock_debug;
_spinunlock;
+ _swapcontext;
/* Debugger needs these. */
_libthr_debug;
@@ -397,4 +399,6 @@ FBSD_1.1 {
FBSD_1.2 {
openat;
+ setcontext;
+ swapcontext;
};
Modified: head/lib/libthr/thread/thr_private.h
==============================================================================
--- head/lib/libthr/thread/thr_private.h Tue Aug 24 08:11:11 2010 (r211736)
+++ head/lib/libthr/thread/thr_private.h Tue Aug 24 09:57:06 2010 (r211737)
@@ -709,6 +709,12 @@ int __sys_sigwaitinfo(const sigset_t *se
int __sys_nanosleep(const struct timespec *, struct timespec *);
#endif
+/* #include <sys/ucontext.h> */
+#ifdef _SYS_UCONTEXT_H_
+int __sys_setcontext(const ucontext_t *ucp);
+int __sys_swapcontext(ucontext_t *oucp, const ucontext_t *ucp);
+#endif
+
/* #include <unistd.h> */
#ifdef _UNISTD_H_
int __sys_close(int);
Modified: head/lib/libthr/thread/thr_sig.c
==============================================================================
--- head/lib/libthr/thread/thr_sig.c Tue Aug 24 08:11:11 2010 (r211736)
+++ head/lib/libthr/thread/thr_sig.c Tue Aug 24 09:57:06 2010 (r211737)
@@ -59,7 +59,29 @@ int _sigwaitinfo(const sigset_t *set, si
int __sigwait(const sigset_t *set, int *sig);
int _sigwait(const sigset_t *set, int *sig);
int __sigsuspend(const sigset_t *sigmask);
+int _setcontext(const ucontext_t *);
+int _swapcontext(ucontext_t *, const ucontext_t *);
+static void
+remove_thr_signals(sigset_t *set)
+{
+ if (SIGISMEMBER(*set, SIGCANCEL))
+ SIGDELSET(*set, SIGCANCEL);
+}
+
+static const sigset_t *
+thr_remove_thr_signals(const sigset_t *set, sigset_t *newset)
+{
+ const sigset_t *pset;
+
+ if (SIGISMEMBER(*set, SIGCANCEL)) {
+ *newset = *set;
+ SIGDELSET(*newset, SIGCANCEL);
+ pset = newset;
+ } else
+ pset = set;
+ return (pset);
+}
static void
sigcancel_handler(int sig __unused,
@@ -268,20 +290,6 @@ _pthread_sigmask(int how, const sigset_t
__weak_reference(__sigsuspend, sigsuspend);
-static const sigset_t *
-thr_remove_thr_signals(const sigset_t *set, sigset_t *newset)
-{
- const sigset_t *pset;
-
- if (SIGISMEMBER(*set, SIGCANCEL)) {
- *newset = *set;
- SIGDELSET(*newset, SIGCANCEL);
- pset = newset;
- } else
- pset = set;
- return (pset);
-}
-
int
_sigsuspend(const sigset_t * set)
{
@@ -389,3 +397,26 @@ __sigwait(const sigset_t *set, int *sig)
_thr_cancel_leave_defer(curthread, (ret != 0));
return (ret);
}
+
+__weak_reference(_setcontext, setcontext);
+int
+_setcontext(const ucontext_t *ucp)
+{
+ ucontext_t uc;
+
+ (void) memcpy(&uc, ucp, sizeof (uc));
+ remove_thr_signals(&uc.uc_sigmask);
+
+ return __sys_setcontext(&uc);
+}
+
+__weak_reference(_swapcontext, swapcontext);
+int
+_swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
+{
+ ucontext_t uc;
+
+ (void) memcpy(&uc, ucp, sizeof (uc));
+ remove_thr_signals(&uc.uc_sigmask);
+ return __sys_swapcontext(oucp, &uc);
+}
More information about the svn-src-all
mailing list