From 42faed412857d4a0069d982d5c8cfe138b7a0197 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 30 Apr 2011 10:20:25 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 9 +++++++++ winsup/cygwin/thread.cc | 16 +++++++++++++--- winsup/cygwin/thread.h | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 08d5533e4..5b0d8ae7b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2011-04-30 Corinna Vinschen + + * 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. + 2011-04-29 Corinna Vinschen * errno.cc (errmap): Sort. Map ERROR_EXE_MACHINE_TYPE_MISMATCH to 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::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; } } diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index f96714f49..2453630f8 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -366,6 +366,7 @@ public: void *return_ptr; bool valid; bool suspended; + bool canceled; int cancelstate, canceltype; _cygtls *cygtls; HANDLE cancel_event; -- 2.43.5