summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/thread.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2011-04-30 10:20:25 +0000
committerCorinna Vinschen <corinna@vinschen.de>2011-04-30 10:20:25 +0000
commit42faed412857d4a0069d982d5c8cfe138b7a0197 (patch)
tree2b37d7f90e68ee5d30834a9c6d7789f2d6d609f9 /winsup/cygwin/thread.cc
parente0b0b9e4ff56b255bb8b2ea9b7e99599ffdbdb56 (diff)
downloadcygnal-42faed412857d4a0069d982d5c8cfe138b7a0197.tar.gz
cygnal-42faed412857d4a0069d982d5c8cfe138b7a0197.tar.bz2
cygnal-42faed412857d4a0069d982d5c8cfe138b7a0197.zip
* thread.h (class pthread): Add bool member canceled.
* thread.cc (pthread::pthread): Initialize canceled to false. (pthread::cancel): Set canceled before setting cancel_event. (pthread::testcancel): Check for canceled. Only wait for cancel_event if canceled is true. Explain why. (pthread::_fixup_after_fork): Set canceled to false.
Diffstat (limited to 'winsup/cygwin/thread.cc')
-rw-r--r--winsup/cygwin/thread.cc16
1 files changed, 13 insertions, 3 deletions
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index a9e5f77c0..10fc2c66b 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -378,7 +378,7 @@ List<pthread> pthread::threads;
/* member methods */
pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
- valid (false), suspended (false),
+ valid (false), suspended (false), canceled (false),
cancelstate (0), canceltype (0), cancel_event (0),
joiner (NULL), next (NULL), cleanup_stack (NULL)
{
@@ -538,6 +538,7 @@ pthread::cancel ()
{
// cancel deferred
mutex.unlock ();
+ canceled = true;
SetEvent (cancel_event);
return 0;
}
@@ -871,8 +872,16 @@ pthread::testcancel ()
if (cancelstate == PTHREAD_CANCEL_DISABLE)
return;
- if (IsEventSignalled (cancel_event))
- cancel_self ();
+ /* We check for the canceled flag first. This allows to use the
+ pthread_testcancel function a lot without adding the overhead of
+ an OS call. Only if the thread is marked as canceled, we wait for
+ cancel_event being really set, on the off-chance that pthread_cancel
+ gets interrupted before calling SetEvent. */
+ if (canceled)
+ {
+ WaitForSingleObject (cancel_event, INFINITE);
+ cancel_self ();
+ }
}
void
@@ -1039,6 +1048,7 @@ pthread::_fixup_after_fork ()
magic = 0;
valid = false;
win32_obj_id = NULL;
+ canceled = false;
cancel_event = NULL;
}
}