From efd76e4140cbdb4e1f6acfbf5c95e5bf6e5dceeb Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Wed, 7 Mar 2001 06:19:34 +0000 Subject: [PATCH] * 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/ChangeLog | 18 ++++++++++++++++-- winsup/cygwin/exceptions.cc | 25 +++++++++++++++++++++++++ winsup/cygwin/path.h | 2 +- winsup/cygwin/sigproc.h | 7 +++++++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 064f610f7..55c86d149 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,17 @@ +Wed Mar 7 01:08:21 2001 Christopher Faylor + + * 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. + Tue Mar 6 14:02:00 2001 Corinna Vinschen * path.cc (suffix_scan::has): Change order of conditionals @@ -211,7 +225,7 @@ Wed Feb 28 15:10:00 2001 Corinna Vinschen default values on reset command. 2001-02-26 Mike Simons - + * times.cc (settimeofday): Replace function stub with working code. Mon Feb 26 10:42:00 2001 Corinna Vinschen @@ -362,7 +376,7 @@ Wed Feb 14 14:54:40 2001 Christophe Iasci the library is not found 2001-02-14 Egor Duda - + * fhandler_console.cc (fhandler_console::char_command): Ignore unknown rendition codes in \033[xx;yym control sequences 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) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 40b8eec5b..bdca965b4 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -36,7 +36,7 @@ enum path_types PATH_BINARY = MOUNT_BINARY, PATH_EXEC = MOUNT_EXEC, PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC, - PATH_ALL_EXEC = PATH_CYGWIN_EXEC | PATH_EXEC, + PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC), PATH_ISDISK = 0x04000000, PATH_NOTEXEC = 0x08000000, PATH_HAS_SYMLINKS = 0x10000000, diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index a5b72bca2..0daa493f5 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -40,6 +40,9 @@ struct sigthread DWORD id; DWORD frame; CRITICAL_SECTION lock; + LONG winapi_lock; + bool get_winapi_lock (int test = 0); + void release_winapi_lock (); void init (const char *s); }; @@ -51,8 +54,11 @@ private: public: void set (sigthread &t, DWORD ebp) { + DWORD oframe = t.frame; st = &t; t.frame = ebp; + if (!oframe) + t.get_winapi_lock (); } sigframe () {st = NULL;} @@ -69,6 +75,7 @@ public: { EnterCriticalSection (&st->lock); st->frame = 0; + st->release_winapi_lock (); LeaveCriticalSection (&st->lock); st = NULL; }