Author: davidxu
Date: Tue Sep 21 06:47:04 2010
New Revision: 212952
URL: http://svn.freebsd.org/changeset/base/212952

Log:
  If we are at cancellation point, always work as deferred mode despite
  whether asynchronous mode is turned on or not, this always gives us a
  chance to decide whether thread should be canceled or not in
  cancellation points.

Modified:
  head/lib/libthr/thread/thr_sig.c

Modified: head/lib/libthr/thread/thr_sig.c
==============================================================================
--- head/lib/libthr/thread/thr_sig.c    Tue Sep 21 05:58:45 2010        
(r212951)
+++ head/lib/libthr/thread/thr_sig.c    Tue Sep 21 06:47:04 2010        
(r212952)
@@ -270,46 +270,44 @@ static void
 check_cancel(struct pthread *curthread, ucontext_t *ucp)
 {
 
-       if (__predict_true(!curthread->cancel_pending || 
!curthread->cancel_enable ||
-           curthread->no_cancel))
+       if (__predict_true(!curthread->cancel_pending ||
+           !curthread->cancel_enable || curthread->no_cancel))
                return;
 
-       if (curthread->cancel_async) {
+       /*
+        * Otherwise, we are in defer mode, and we are at
+        * cancel point, tell kernel to not block the current
+        * thread on next cancelable system call.
+        * 
+        * There are three cases we should call thr_wake() to
+        * turn on TDP_WAKEUP or send SIGCANCEL in kernel:
+        * 1) we are going to call a cancelable system call,
+        *    non-zero cancel_point means we are already in
+        *    cancelable state, next system call is cancelable.
+        * 2) because _thr_ast() may be called by
+        *    THR_CRITICAL_LEAVE() which is used by rtld rwlock
+        *    and any libthr internal locks, when rtld rwlock
+        *    is used, it is mostly caused my an unresolved PLT.
+        *    those routines may clear the TDP_WAKEUP flag by
+        *    invoking some system calls, in those cases, we
+        *    also should reenable the flag.
+        * 3) thread is in sigsuspend(), and the syscall insists
+        *    on getting a signal before it agrees to return.
+        */
+       if (curthread->cancel_point) {
+               if (curthread->in_sigsuspend && ucp) {
+                       SIGADDSET(ucp->uc_sigmask, SIGCANCEL);
+                       curthread->unblock_sigcancel = 1;
+                       _thr_send_sig(curthread, SIGCANCEL);
+               } else
+                       thr_wake(curthread->tid);
+       } else if (curthread->cancel_async) {
                /*
-                * asynchronous cancellation mode, act upon
+                * asynchronous cancellation mode, act upon
                 * immediately.
-                */
+                */
                _pthread_exit_mask(PTHREAD_CANCELED,
                    ucp? &ucp->uc_sigmask : NULL);
-       } else {
-               /*
-                * Otherwise, we are in defer mode, and we are at
-                * cancel point, tell kernel to not block the current
-                * thread on next cancelable system call.
-                * 
-                * There are three cases we should call thr_wake() to
-                * turn on TDP_WAKEUP or send SIGCANCEL in kernel:
-                * 1) we are going to call a cancelable system call,
-                *    non-zero cancel_point means we are already in
-                *    cancelable state, next system call is cancelable.
-                * 2) because _thr_ast() may be called by
-                *    THR_CRITICAL_LEAVE() which is used by rtld rwlock
-                *    and any libthr internal locks, when rtld rwlock
-                *    is used, it is mostly caused my an unresolved PLT.
-                *    those routines may clear the TDP_WAKEUP flag by
-                *    invoking some system calls, in those cases, we
-                *    also should reenable the flag.
-                * 3) thread is in sigsuspend(), and the syscall insists
-                *    on getting a signal before it agrees to return.
-                */
-               if (curthread->cancel_point) {
-                       if (curthread->in_sigsuspend && ucp) {
-                               SIGADDSET(ucp->uc_sigmask, SIGCANCEL);
-                               curthread->unblock_sigcancel = 1;
-                               _thr_send_sig(curthread, SIGCANCEL);
-                       } else
-                               thr_wake(curthread->tid);
-               }
        }
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to