diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2011-04-30 10:20:25 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2011-04-30 10:20:25 +0000 |
commit | 42faed412857d4a0069d982d5c8cfe138b7a0197 (patch) | |
tree | 2b37d7f90e68ee5d30834a9c6d7789f2d6d609f9 /winsup/cygwin/thread.cc | |
parent | e0b0b9e4ff56b255bb8b2ea9b7e99599ffdbdb56 (diff) | |
download | cygnal-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.cc | 16 |
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; } } |