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