Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2012-05-23 17:30:26 +0400
committerCorinna Vinschen <corinna@vinschen.de>2012-05-23 17:30:26 +0400
commit86b35406f22202a3c382ca06551e5c0fa3a0e628 (patch)
treeb0fb6613da3799c017fa7e577ee37a9752ee8525 /winsup/cygwin/thread.cc
parent750329ae90b72713963e4236c17e7f0bd167e4a3 (diff)
* thread.cc (pthread::cancel): Only allow asynchronous cancellation
if the thread is not executing Cygwin or Windows code. Explain why.
Diffstat (limited to 'winsup/cygwin/thread.cc')
-rw-r--r--winsup/cygwin/thread.cc23
1 files changed, 21 insertions, 2 deletions
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 7a914b281..e83666bc9 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -569,11 +569,30 @@ pthread::cancel ()
SuspendThread (win32_obj_id);
if (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT)
{
+ static uintptr_t cyg_addr;
CONTEXT context;
context.ContextFlags = CONTEXT_CONTROL;
GetThreadContext (win32_obj_id, &context);
- context.Eip = (DWORD) pthread::static_cancel_self;
- SetThreadContext (win32_obj_id, &context);
+ /* FIXME:
+
+ File access (and probably more) in Cygwin is not foolproof in terms of
+ asynchronous thread cancellation. For instance, the cleanup of the
+ tmp_buf pointers needs to be changed to use pthread_cleanup_push/pop,
+ rather than being hidden in the myfault class. We have to inspect
+ all Cygwin functions so that none of them is left in a wrong or
+ undefined state on thread cancellation.
+
+ For the time being, just disable asynchronous cancellation if the
+ thread is currently executing Cygwin or Windows code. Rely on
+ deferred cancellation in this case. */
+ if (!cyg_addr)
+ cyg_addr = (uintptr_t) GetModuleHandle ("cygwin1.dll");
+ if ((context.Eip < cyg_addr || context.Eip >= (uintptr_t) cygheap)
+ && !cygtls->inside_kernel (&context))
+ {
+ context.Eip = (DWORD) pthread::static_cancel_self;
+ SetThreadContext (win32_obj_id, &context);
+ }
}
mutex.unlock ();
/* Setting the context to another function does not work if the thread is