* 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.
This commit is contained in:
Christopher Faylor
2001-03-07 06:19:34 +00:00
parent 25ee9ae285
commit efd76e4140
4 changed files with 49 additions and 3 deletions

View File

@ -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)