diff options
author | Christopher Faylor <me@cgf.cx> | 2001-03-07 06:19:34 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2001-03-07 06:19:34 +0000 |
commit | efd76e4140cbdb4e1f6acfbf5c95e5bf6e5dceeb (patch) | |
tree | c4d56fa1118655ddf32c9e0beaacd23524787670 /winsup/cygwin/exceptions.cc | |
parent | 25ee9ae28513c5cee6ade2c1cdc12984c8639491 (diff) | |
download | cygnal-efd76e4140cbdb4e1f6acfbf5c95e5bf6e5dceeb.tar.gz cygnal-efd76e4140cbdb4e1f6acfbf5c95e5bf6e5dceeb.tar.bz2 cygnal-efd76e4140cbdb4e1f6acfbf5c95e5bf6e5dceeb.zip |
* 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.
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r-- | winsup/cygwin/exceptions.cc | 25 |
1 files changed, 25 insertions, 0 deletions
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) |