Author: bonefish Date: 2011-06-07 00:32:50 +0200 (Tue, 07 Jun 2011) New Revision: 41990 Changeset: https://dev.haiku-os.org/changeset/41990 Modified: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/pthread/pthread_cancel.cpp Log: pthread_cancel(): Call _kernel_cancel_thread() also when the thread hasn't set the asynchronous cancellation flag. Otherwise we wouldn't interrupt a syscall. Modified: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/pthread/pthread_cancel.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/libroot/posix/pthread/pthread_cancel.cpp 2011-06-06 22:28:26 UTC (rev 41989) +++ haiku/branches/developer/bonefish/signals/src/system/libroot/posix/pthread/pthread_cancel.cpp 2011-06-06 22:32:50 UTC (rev 41990) @@ -21,14 +21,19 @@ } -/*! Invoked when the thread is canceled asynchronously. +/*! Signal handler like function invoked when this thread has been canceled. Has the simple signal handler signature, since it is invoked just like a signal handler. */ static void asynchronous_cancel_thread(int) { - pthread_exit(PTHREAD_CANCELED); + pthread_t thread = pthread_self(); + + // Exit when asynchronous cancellation is enabled, otherwise we don't have + // to do anything -- the syscall interrupting side effect is all we need. + if ((atomic_get(&thread->flags) & THREAD_CANCEL_ASYNCHRONOUS) != 0) + pthread_exit(PTHREAD_CANCELED); } @@ -45,11 +50,9 @@ if ((oldFlags & THREAD_CANCELED) != 0) return 0; - // check whether the thread is supposed to be canceled asynchronously - static const int32 kFlags = THREAD_CANCEL_ENABLED - | THREAD_CANCEL_ASYNCHRONOUS; - - if ((~oldFlags & kFlags) == 0) + // If cancellation is enabled, notify the thread. This will call the + // asynchronous_cancel_thread() handler. + if ((oldFlags & THREAD_CANCEL_ENABLED) != 0) return _kern_cancel_thread(thread->id, &asynchronous_cancel_thread); return 0;