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);
+}
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to