summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libthr/thread/thr_sig.c66
1 files changed, 32 insertions, 34 deletions
diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c
index a9b8d1c..a2c1e53 100644
--- a/lib/libthr/thread/thr_sig.c
+++ b/lib/libthr/thread/thr_sig.c
@@ -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);
- }
}
}
OpenPOWER on IntegriCloud