diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2012-05-23 13:30:26 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2012-05-23 13:30:26 +0000 |
commit | 86b35406f22202a3c382ca06551e5c0fa3a0e628 (patch) | |
tree | b0fb6613da3799c017fa7e577ee37a9752ee8525 | |
parent | 750329ae90b72713963e4236c17e7f0bd167e4a3 (diff) | |
download | newlib-86b35406f22202a3c382ca06551e5c0fa3a0e628.zip newlib-86b35406f22202a3c382ca06551e5c0fa3a0e628.tar.gz newlib-86b35406f22202a3c382ca06551e5c0fa3a0e628.tar.bz2 |
* thread.cc (pthread::cancel): Only allow asynchronous cancellation
if the thread is not executing Cygwin or Windows code. Explain why.
-rw-r--r-- | winsup/cygwin/ChangeLog | 5 | ||||
-rw-r--r-- | winsup/cygwin/thread.cc | 23 |
2 files changed, 26 insertions, 2 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 7b3d56d..9baeb4d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,10 @@ 2012-05-23 Corinna Vinschen <corinna@vinschen.de> + * thread.cc (pthread::cancel): Only allow asynchronous cancellation + if the thread is not executing Cygwin or Windows code. Explain why. + +2012-05-23 Corinna Vinschen <corinna@vinschen.de> + * thread.cc (pthread::precreate): Make sure mutex is recursive. Explain why. diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 7a914b2..e83666b 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 |