From efd76e4140cbdb4e1f6acfbf5c95e5bf6e5dceeb Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Wed, 7 Mar 2001 06:19:34 +0000 Subject: * sigproc.h (sigthread): Declare new methods. Create new winapi_lock field. (sigframe:;set): Call get_winapi_lock after frame is set so that signal handler thread knows not to call SuspendThread. (sigframe::~sigframe): Release winapi_lock. * exceptions.cc (sigthread::get_winapi_lock): New method. (sigthread::release_winapi_lock): New method. (setup_handler): Use get_winapi_lock to ensure that signalled thread is not blocked in a Windows API. * path.h (path_types): Avoid broken GCC warning. --- winsup/cygwin/exceptions.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'winsup/cygwin/exceptions.cc') diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 532f1d2aa..dc5b7fb72 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -647,6 +647,26 @@ interruptible (DWORD pc, int testvalid = 0) return res; } +bool +sigthread::get_winapi_lock (int test) +{ + if (test) + return !InterlockedExchange (&winapi_lock, 1); + + /* Need to do a busy loop because we can't block or a potential SuspendThread + will hang. */ + while (InterlockedExchange (&winapi_lock, 1)) + Sleep (1); + return 1; +} + +void +sigthread::release_winapi_lock () +{ + /* Assumes that we have the lock. */ + InterlockedExchange (&winapi_lock, 0); +} + static void __stdcall interrupt_setup (int sig, void *handler, DWORD retaddr, DWORD *retaddr_on_stack, struct sigaction& siga) @@ -778,8 +798,13 @@ setup_handler (int sig, void *handler, struct sigaction& siga) If the thread is already suspended (which can occur when a program is stopped) then just queue the signal. */ + if (!mainthread.get_winapi_lock (1)) + continue; sigproc_printf ("suspending mainthread"); res = SuspendThread (hth); + mainthread.release_winapi_lock (); + if (mainthread.frame) + goto resume_thread; /* In case the main thread *just* set the frame */ /* Just set pending if thread is already suspended */ if (res) -- cgit v1.2.3