* 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>
|
2002-11-20 Pierre Humblet <pierre.humblet@ieee.org>
|
||||||
|
|
||||||
* security.h: Declare internal_getpwsid and internal_getgrsid.
|
* 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
|
/* Need to do a busy loop because we can't block or a potential SuspendThread
|
||||||
will hang. */
|
will hang. */
|
||||||
while (InterlockedExchange (&winapi_lock, 1))
|
while (InterlockedExchange (&winapi_lock, 1))
|
||||||
low_priority_sleep (1);
|
low_priority_sleep (0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,26 +782,33 @@ static int
|
|||||||
setup_handler (int sig, void *handler, struct sigaction& siga)
|
setup_handler (int sig, void *handler, struct sigaction& siga)
|
||||||
{
|
{
|
||||||
CONTEXT cx;
|
CONTEXT cx;
|
||||||
bool interrupted = 0;
|
bool interrupted = false;
|
||||||
HANDLE hth = NULL;
|
|
||||||
int res;
|
|
||||||
sigthread *th = NULL; // Initialization needed to shut up gcc
|
sigthread *th = NULL; // Initialization needed to shut up gcc
|
||||||
|
int prio = INFINITE;
|
||||||
|
|
||||||
if (sigsave.sig)
|
if (sigsave.sig)
|
||||||
goto set_pending;
|
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);
|
EnterCriticalSection (&mainthread.lock);
|
||||||
if (mainthread.frame)
|
if (mainthread.frame)
|
||||||
th = &mainthread;
|
{
|
||||||
|
hth = NULL;
|
||||||
|
th = &mainthread;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LeaveCriticalSection (&mainthread.lock);
|
LeaveCriticalSection (&mainthread.lock);
|
||||||
|
|
||||||
th = NULL;
|
if (!mainthread.get_winapi_lock (1))
|
||||||
|
continue;
|
||||||
|
|
||||||
hth = myself->getthread2signal ();
|
hth = myself->getthread2signal ();
|
||||||
|
th = NULL;
|
||||||
|
|
||||||
/* Suspend the thread which will receive the signal. But first ensure that
|
/* 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
|
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
|
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
|
since we don't want to stall the signal handler. FIXME: Will this result in
|
||||||
noticeable delays?
|
noticeable delays?
|
||||||
If the thread is already suspended (which can occur when a program is stopped) then
|
If the thread is already suspended (which can occur when a program has called
|
||||||
just queue the signal. */
|
SuspendThread on itself then just queue the signal. */
|
||||||
|
|
||||||
if (!mainthread.get_winapi_lock (1))
|
EnterCriticalSection (&mainthread.lock);
|
||||||
continue;
|
|
||||||
sigproc_printf ("suspending mainthread");
|
sigproc_printf ("suspending mainthread");
|
||||||
res = SuspendThread (hth);
|
res = SuspendThread (hth);
|
||||||
mainthread.release_winapi_lock ();
|
/* Just release the lock now since we hav suspended the main thread and it
|
||||||
if (mainthread.frame)
|
definitely can't be grabbing it now. This will have to change, of course,
|
||||||
goto resume_thread; /* In case the main thread *just* set the frame */
|
if/when we can send signals to other than the main thread. */
|
||||||
|
LeaveCriticalSection (&mainthread.lock);
|
||||||
|
|
||||||
/* Just set pending if thread is already suspended */
|
/* Just set pending if thread is already suspended */
|
||||||
if (res)
|
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;
|
muto *m;
|
||||||
/* FIXME: Make multi-thread aware */
|
/* FIXME: Make multi-thread aware */
|
||||||
@ -835,71 +851,63 @@ setup_handler (int sig, void *handler, struct sigaction& siga)
|
|||||||
goto resume_thread;
|
goto resume_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterCriticalSection (&mainthread.lock);
|
|
||||||
if (mainthread.frame)
|
if (mainthread.frame)
|
||||||
{
|
th = &mainthread;
|
||||||
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);
|
|
||||||
else
|
else
|
||||||
goto try_to_interrupt;
|
{
|
||||||
|
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
||||||
resume_thread:
|
if (!GetThreadContext (hth, &cx))
|
||||||
ResumeThread (hth);
|
{
|
||||||
low_priority_sleep (0);
|
system_printf ("couldn't get context of main thread, %E");
|
||||||
continue;
|
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)
|
if (th)
|
||||||
{
|
{
|
||||||
interrupted = interrupt_on_return (th, sig, handler, siga);
|
interrupted = interrupt_on_return (th, sig, handler, siga);
|
||||||
LeaveCriticalSection (&th->lock);
|
LeaveCriticalSection (&th->lock);
|
||||||
}
|
}
|
||||||
else if (interruptible (cx.Eip))
|
else if (interruptible (cx.Eip))
|
||||||
{
|
interrupted = interrupt_now (&cx, sig, handler, siga);
|
||||||
interrupted = interrupt_now (&cx, sig, handler, siga);
|
|
||||||
#ifdef DEBUGGING
|
resume_thread:
|
||||||
if (!interrupted)
|
if (hth)
|
||||||
sigproc_printf ("couldn't deliver signal %d via %p", sig, cx.Eip);
|
res = ResumeThread (hth);
|
||||||
#endif
|
|
||||||
}
|
if (interrupted)
|
||||||
else
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if ((DWORD) prio != INFINITE && !mainthread.frame)
|
||||||
|
prio = low_priority_sleep (SLEEP_0_STAY_LOW);
|
||||||
|
sigproc_printf ("couldn't interrupt. trying again.");
|
||||||
}
|
}
|
||||||
|
|
||||||
set_pending:
|
set_pending:
|
||||||
if (interrupted)
|
if (interrupted)
|
||||||
res = 1;
|
{
|
||||||
|
if ((DWORD) prio != INFINITE)
|
||||||
|
SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
|
||||||
|
sigproc_printf ("signal successfully delivered");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pending_signals = 1; /* FIXME: Probably need to be more tricky here */
|
pending_signals = 1; /* FIXME: Probably need to be more tricky here */
|
||||||
sig_set_pending (sig);
|
sig_set_pending (sig);
|
||||||
sig_dispatch_pending (1);
|
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);
|
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);
|
sigproc_printf ("returning %d", interrupted);
|
||||||
if (pending_signals)
|
|
||||||
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
|
|
||||||
return interrupted;
|
return interrupted;
|
||||||
}
|
}
|
||||||
#endif /* i386 */
|
#endif /* i386 */
|
||||||
|
@ -292,12 +292,27 @@ sys_mbstowcs (WCHAR *tgt, const char *src, int len)
|
|||||||
return MultiByteToWideChar (get_cp (), 0, src, -1, tgt, len);
|
return MultiByteToWideChar (get_cp (), 0, src, -1, tgt, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall
|
int __stdcall
|
||||||
low_priority_sleep (DWORD secs)
|
low_priority_sleep (DWORD secs)
|
||||||
{
|
{
|
||||||
HANDLE thisthread = GetCurrentThread ();
|
HANDLE thisthread = GetCurrentThread ();
|
||||||
int curr_prio = GetThreadPriority (thisthread);
|
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);
|
SetThreadPriority (thisthread, THREAD_PRIORITY_IDLE);
|
||||||
Sleep (secs);
|
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_handler = func;
|
||||||
myself->getsig (sig).sa_mask = 0;
|
myself->getsig (sig).sa_mask = 0;
|
||||||
/* SA_RESTART is set to maintain BSD compatible signal behaviour by default.
|
/* 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;
|
myself->getsig (sig).sa_flags |= SA_RESTART;
|
||||||
set_sigcatchers (prev, func);
|
set_sigcatchers (prev, func);
|
||||||
|
|
||||||
|
@ -41,8 +41,6 @@ details. */
|
|||||||
#define WSPX 20000 // Wait for wait_sig to terminate
|
#define WSPX 20000 // Wait for wait_sig to terminate
|
||||||
#define WWSP 20000 // Wait for wait_subproc to terminate
|
#define WWSP 20000 // Wait for wait_subproc to terminate
|
||||||
|
|
||||||
#define WAIT_SIG_PRIORITY THREAD_PRIORITY_TIME_CRITICAL
|
|
||||||
|
|
||||||
#define TOTSIGS (NSIG + __SIGOFFSET)
|
#define TOTSIGS (NSIG + __SIGOFFSET)
|
||||||
|
|
||||||
#define wake_wait_subproc() SetEvent (events[0])
|
#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_dummy[];
|
||||||
extern char myself_nowait_nonmain_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 ((_pinfo *)myself_nowait_dummy)
|
||||||
#define myself_nowait_nonmain ((_pinfo *)myself_nowait_nonmain_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;
|
class path_conv;
|
||||||
int __stdcall stat_worker (const char *name, struct __stat64 *buf, int nofollow,
|
int __stdcall stat_worker (const char *name, struct __stat64 *buf, int nofollow,
|
||||||
path_conv *pc = NULL) __attribute__ ((regparm (3)));
|
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 ******************************/
|
/**************************** Exports ******************************/
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user