svn commit: r212952 - head/lib/libthr/thread

David Xu davidxu at FreeBSD.org
Tue Sep 21 06:47:05 UTC 2010


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);
-		}
 	}
 }
 


More information about the svn-src-all mailing list