* exceptions.cc (sigthread::get_winapi_lock): Just do standard 'give up
timeslice' wait. (setup_handler): Revamp YA to attempt to deliver signal multiple times on failure rather than punting to wait_sig. * miscfuncs.cc (low_priority_sleep): Accept INFINITE sleep to mean "don't reset the priority after setting it to idle". Return previous priority. * winsup.h (SLEEP_0_STAY_LOW): Define. (low_priority_sleep): Return an int. * sigproc.h: Define WAIT_SIG_PRIORITY here. * sigproc.cc: Remove WAIT_SIG_PRIORITY definition.
This commit is contained in:
parent
505746ad22
commit
13af9a149d
|
@ -1,3 +1,17 @@
|
|||
2002-11-21 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* exceptions.cc (sigthread::get_winapi_lock): Just do standard 'give up
|
||||
timeslice' wait.
|
||||
(setup_handler): Revamp YA to attempt to deliver signal multiple times
|
||||
on failure rather than punting to wait_sig.
|
||||
* miscfuncs.cc (low_priority_sleep): Accept INFINITE sleep to mean
|
||||
"don't reset the priority after setting it to idle". Return previous
|
||||
priority.
|
||||
* winsup.h (SLEEP_0_STAY_LOW): Define.
|
||||
(low_priority_sleep): Return an int.
|
||||
* sigproc.h: Define WAIT_SIG_PRIORITY here.
|
||||
* sigproc.cc: Remove WAIT_SIG_PRIORITY definition.
|
||||
|
||||
2002-11-20 Pierre Humblet <pierre.humblet@ieee.org>
|
||||
|
||||
* security.h: Declare internal_getpwsid and internal_getgrsid.
|
||||
|
|
|
@ -666,7 +666,7 @@ sigthread::get_winapi_lock (int test)
|
|||
/* Need to do a busy loop because we can't block or a potential SuspendThread
|
||||
will hang. */
|
||||
while (InterlockedExchange (&winapi_lock, 1))
|
||||
low_priority_sleep (1);
|
||||
low_priority_sleep (0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -782,26 +782,33 @@ static int
|
|||
setup_handler (int sig, void *handler, struct sigaction& siga)
|
||||
{
|
||||
CONTEXT cx;
|
||||
bool interrupted = 0;
|
||||
HANDLE hth = NULL;
|
||||
int res;
|
||||
bool interrupted = false;
|
||||
sigthread *th = NULL; // Initialization needed to shut up gcc
|
||||
int prio = INFINITE;
|
||||
|
||||
if (sigsave.sig)
|
||||
goto set_pending;
|
||||
|
||||
for (int i = 0; !interrupted && i < CALL_HANDLER_RETRY; i++)
|
||||
for (int i = 0; i < CALL_HANDLER_RETRY; i++)
|
||||
{
|
||||
DWORD res;
|
||||
HANDLE hth;
|
||||
|
||||
EnterCriticalSection (&mainthread.lock);
|
||||
if (mainthread.frame)
|
||||
th = &mainthread;
|
||||
{
|
||||
hth = NULL;
|
||||
th = &mainthread;
|
||||
}
|
||||
else
|
||||
{
|
||||
LeaveCriticalSection (&mainthread.lock);
|
||||
|
||||
th = NULL;
|
||||
if (!mainthread.get_winapi_lock (1))
|
||||
continue;
|
||||
|
||||
hth = myself->getthread2signal ();
|
||||
th = NULL;
|
||||
|
||||
/* Suspend the thread which will receive the signal. But first ensure that
|
||||
this thread doesn't have any mutos. (FIXME: Someday we should just grab
|
||||
|
@ -811,20 +818,29 @@ setup_handler (int sig, void *handler, struct sigaction& siga)
|
|||
If one of these conditions is not true we loop for a fixed number of times
|
||||
since we don't want to stall the signal handler. FIXME: Will this result in
|
||||
noticeable delays?
|
||||
If the thread is already suspended (which can occur when a program is stopped) then
|
||||
just queue the signal. */
|
||||
If the thread is already suspended (which can occur when a program has called
|
||||
SuspendThread on itself then just queue the signal. */
|
||||
|
||||
if (!mainthread.get_winapi_lock (1))
|
||||
continue;
|
||||
EnterCriticalSection (&mainthread.lock);
|
||||
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 release the lock now since we hav suspended the main thread and it
|
||||
definitely can't be grabbing it now. This will have to change, of course,
|
||||
if/when we can send signals to other than the main thread. */
|
||||
LeaveCriticalSection (&mainthread.lock);
|
||||
|
||||
/* Just set pending if thread is already suspended */
|
||||
if (res)
|
||||
goto set_pending;
|
||||
{
|
||||
(void) ResumeThread (hth);
|
||||
break;
|
||||
}
|
||||
|
||||
mainthread.release_winapi_lock ();
|
||||
if (mainthread.frame)
|
||||
goto resume_thread; /* We just got the frame. What are the odds?
|
||||
Just loop and we'll hopefully pick it up on
|
||||
the next pass through. */
|
||||
|
||||
muto *m;
|
||||
/* FIXME: Make multi-thread aware */
|
||||
|
@ -835,71 +851,63 @@ setup_handler (int sig, void *handler, struct sigaction& siga)
|
|||
goto resume_thread;
|
||||
}
|
||||
|
||||
EnterCriticalSection (&mainthread.lock);
|
||||
if (mainthread.frame)
|
||||
{
|
||||
th = &mainthread;
|
||||
goto try_to_interrupt;
|
||||
}
|
||||
|
||||
LeaveCriticalSection (&mainthread.lock);
|
||||
|
||||
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
||||
if (!GetThreadContext (hth, &cx))
|
||||
system_printf ("couldn't get context of main thread, %E");
|
||||
else if (!interruptible (cx.Eip, 1))
|
||||
sigproc_printf ("suspended thread in a strange state pc %p, sp %p",
|
||||
cx.Eip, cx.Esp);
|
||||
th = &mainthread;
|
||||
else
|
||||
goto try_to_interrupt;
|
||||
|
||||
resume_thread:
|
||||
ResumeThread (hth);
|
||||
low_priority_sleep (0);
|
||||
continue;
|
||||
{
|
||||
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
||||
if (!GetThreadContext (hth, &cx))
|
||||
{
|
||||
system_printf ("couldn't get context of main thread, %E");
|
||||
goto resume_thread;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((DWORD) prio != INFINITE)
|
||||
{
|
||||
/* Reset the priority so we can finish this off quickly. */
|
||||
SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
|
||||
prio = INFINITE;
|
||||
}
|
||||
|
||||
try_to_interrupt:
|
||||
if (th)
|
||||
{
|
||||
interrupted = interrupt_on_return (th, sig, handler, siga);
|
||||
LeaveCriticalSection (&th->lock);
|
||||
}
|
||||
else if (interruptible (cx.Eip))
|
||||
{
|
||||
interrupted = interrupt_now (&cx, sig, handler, siga);
|
||||
#ifdef DEBUGGING
|
||||
if (!interrupted)
|
||||
sigproc_printf ("couldn't deliver signal %d via %p", sig, cx.Eip);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
interrupted = interrupt_now (&cx, sig, handler, siga);
|
||||
|
||||
resume_thread:
|
||||
if (hth)
|
||||
res = ResumeThread (hth);
|
||||
|
||||
if (interrupted)
|
||||
break;
|
||||
|
||||
if ((DWORD) prio != INFINITE && !mainthread.frame)
|
||||
prio = low_priority_sleep (SLEEP_0_STAY_LOW);
|
||||
sigproc_printf ("couldn't interrupt. trying again.");
|
||||
}
|
||||
|
||||
set_pending:
|
||||
if (interrupted)
|
||||
res = 1;
|
||||
{
|
||||
if ((DWORD) prio != INFINITE)
|
||||
SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
|
||||
sigproc_printf ("signal successfully delivered");
|
||||
}
|
||||
else
|
||||
{
|
||||
pending_signals = 1; /* FIXME: Probably need to be more tricky here */
|
||||
sig_set_pending (sig);
|
||||
sig_dispatch_pending (1);
|
||||
low_priority_sleep (0); /* Hopefully, other process will be waking up soon. */
|
||||
low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other process will be waking up soon. */
|
||||
sigproc_printf ("couldn't send signal %d", sig);
|
||||
}
|
||||
|
||||
if (!hth)
|
||||
sigproc_printf ("good. Didn't suspend main thread, th %p", th);
|
||||
else
|
||||
{
|
||||
res = ResumeThread (hth);
|
||||
sigproc_printf ("ResumeThread returned %d", res);
|
||||
}
|
||||
|
||||
sigproc_printf ("returning %d", interrupted);
|
||||
if (pending_signals)
|
||||
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
|
||||
return interrupted;
|
||||
}
|
||||
#endif /* i386 */
|
||||
|
|
|
@ -292,12 +292,27 @@ sys_mbstowcs (WCHAR *tgt, const char *src, int len)
|
|||
return MultiByteToWideChar (get_cp (), 0, src, -1, tgt, len);
|
||||
}
|
||||
|
||||
void __stdcall
|
||||
int __stdcall
|
||||
low_priority_sleep (DWORD secs)
|
||||
{
|
||||
HANDLE thisthread = GetCurrentThread ();
|
||||
int curr_prio = GetThreadPriority (thisthread);
|
||||
bool staylow;
|
||||
if (secs != INFINITE)
|
||||
staylow = false;
|
||||
else
|
||||
{
|
||||
secs = 0;
|
||||
staylow = true;
|
||||
}
|
||||
|
||||
/* Force any threads in normal priority to be scheduled */
|
||||
SetThreadPriority (thisthread, THREAD_PRIORITY_NORMAL);
|
||||
Sleep (0);
|
||||
|
||||
SetThreadPriority (thisthread, THREAD_PRIORITY_IDLE);
|
||||
Sleep (secs);
|
||||
SetThreadPriority (thisthread, curr_prio);
|
||||
if (!staylow)
|
||||
SetThreadPriority (thisthread, curr_prio);
|
||||
return curr_prio;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ signal (int sig, _sig_func_ptr func)
|
|||
myself->getsig (sig).sa_handler = func;
|
||||
myself->getsig (sig).sa_mask = 0;
|
||||
/* SA_RESTART is set to maintain BSD compatible signal behaviour by default.
|
||||
This is also compatible to the behaviour of signal(2) in Linux. */
|
||||
This is also compatible with the behaviour of signal(2) in Linux. */
|
||||
myself->getsig (sig).sa_flags |= SA_RESTART;
|
||||
set_sigcatchers (prev, func);
|
||||
|
||||
|
|
|
@ -41,8 +41,6 @@ details. */
|
|||
#define WSPX 20000 // Wait for wait_sig to terminate
|
||||
#define WWSP 20000 // Wait for wait_subproc to terminate
|
||||
|
||||
#define WAIT_SIG_PRIORITY THREAD_PRIORITY_TIME_CRITICAL
|
||||
|
||||
#define TOTSIGS (NSIG + __SIGOFFSET)
|
||||
|
||||
#define wake_wait_subproc() SetEvent (events[0])
|
||||
|
|
|
@ -124,7 +124,7 @@ void __stdcall wait_for_sigthread ();
|
|||
extern char myself_nowait_dummy[];
|
||||
extern char myself_nowait_nonmain_dummy[];
|
||||
|
||||
#define WAIT_SIG_EXITING (WAIT_OBJECT_0 + 1)
|
||||
#define WAIT_SIG_PRIORITY THREAD_PRIORITY_TIME_CRITICAL
|
||||
|
||||
#define myself_nowait ((_pinfo *)myself_nowait_dummy)
|
||||
#define myself_nowait_nonmain ((_pinfo *)myself_nowait_nonmain_dummy)
|
||||
|
|
|
@ -242,7 +242,8 @@ extern void multiple_cygwin_problem (const char *, unsigned, unsigned);
|
|||
class path_conv;
|
||||
int __stdcall stat_worker (const char *name, struct __stat64 *buf, int nofollow,
|
||||
path_conv *pc = NULL) __attribute__ ((regparm (3)));
|
||||
void __stdcall low_priority_sleep (DWORD) __attribute__ ((regparm (1)));
|
||||
int __stdcall low_priority_sleep (DWORD) __attribute__ ((regparm (1)));
|
||||
#define SLEEP_0_STAY_LOW INFINITE
|
||||
|
||||
/**************************** Exports ******************************/
|
||||
|
||||
|
|
Loading…
Reference in New Issue