Commit 439eaa9f authored by Jack Jansen's avatar Jack Jansen

Fixed various problems with command-dot handling (some very old):

- Don't scan for cmd-. unless in the foreground
- Scan before switching out to other processes, not after
- don't scan if SchedParams.check_interrupt is false (!)
  - But: do scan if we're blocked on I/O

One problem remains: in the last case KeyboardInterrupt is raised
too late.
parent 94ead57d
...@@ -298,12 +298,21 @@ PyMac_GUSISpin(spin_msg msg, long arg) ...@@ -298,12 +298,21 @@ PyMac_GUSISpin(spin_msg msg, long arg)
SpinCursor(msg == SP_AUTO_SPIN ? short(arg) : 1); SpinCursor(msg == SP_AUTO_SPIN ? short(arg) : 1);
#endif #endif
if (interrupted) return -1;
if ( msg == SP_AUTO_SPIN ) if ( msg == SP_AUTO_SPIN )
maxsleep = 0; maxsleep = 0;
if ( msg==SP_SLEEP||msg==SP_SELECT ) if ( msg==SP_SLEEP||msg==SP_SELECT ) {
maxsleep = arg; maxsleep = arg;
/*
** We force-scan for interrupts. Not pretty, but otherwise
** a program may hang in select or sleep forever.
*/
scan_event_queue(1);
}
if (interrupted) {
interrupted = 0;
return -1;
}
PyMac_DoYield(maxsleep, 0); /* XXXX or is it safe to call python here? */ PyMac_DoYield(maxsleep, 0); /* XXXX or is it safe to call python here? */
...@@ -453,23 +462,43 @@ PyOS_FiniInterrupts() ...@@ -453,23 +462,43 @@ PyOS_FiniInterrupts()
{ {
} }
/* Check whether we are in the foreground */
static int
PyMac_InForeground(void)
{
static ProcessSerialNumber ours;
static inited;
ProcessSerialNumber curfg;
Boolean eq;
if ( inited == 0 ) {
(void)GetCurrentProcess(&ours);
inited = 1;
}
if ( GetFrontProcess(&curfg) < 0 )
eq = 1;
else if ( SameProcess(&ours, &curfg, &eq) < 0 )
eq = 1;
return (int)eq;
}
/* /*
** This routine scans the event queue looking for cmd-. ** This routine scans the event queue looking for cmd-.
** This is the only way to get an interrupt under THINK (since it
** doesn't do SIGINT handling), but is also used under MW, when
** the full-fledged event loop is disabled. This way, we can at least
** interrupt a runaway python program.
*/ */
static void static void
scan_event_queue(flush) scan_event_queue(force)
int flush; int force;
{ {
#if !TARGET_API_MAC_OS8 #if !TARGET_API_MAC_OS8
if ( interrupted || (!schedparams.check_interrupt && !force) )
return;
if ( CheckEventQueueForUserCancel() ) if ( CheckEventQueueForUserCancel() )
interrupted = 1; interrupted = 1;
#else #else
register EvQElPtr q; register EvQElPtr q;
if ( interrupted || (!schedparams.check_interrupt && !force) || !PyMac_InForeground() )
return;
q = (EvQElPtr) LMGetEventQueue()->qHead; q = (EvQElPtr) LMGetEventQueue()->qHead;
for (; q; q = (EvQElPtr)q->qLink) { for (; q; q = (EvQElPtr)q->qLink) {
...@@ -488,18 +517,22 @@ scan_event_queue(flush) ...@@ -488,18 +517,22 @@ scan_event_queue(flush)
int int
PyErr_CheckSignals() PyErr_CheckSignals()
{ {
int xxx, xxx_old;
if (schedparams.enabled) { if (schedparams.enabled) {
if ( (unsigned long)LMGetTicks() > schedparams.next_check ) { if ( interrupted || (unsigned long)LMGetTicks() > schedparams.next_check ) {
if ( PyMac_Yield() < 0) scan_event_queue(0);
return -1;
schedparams.next_check = (unsigned long)LMGetTicks()
+ schedparams.check_interval;
if (interrupted) { if (interrupted) {
scan_event_queue(1); /* Eat events up to cmd-. */
interrupted = 0; interrupted = 0;
PyErr_SetNone(PyExc_KeyboardInterrupt); PyErr_SetNone(PyExc_KeyboardInterrupt);
return -1; return -1;
} }
if ( PyMac_Yield() < 0)
return -1;
xxx = LMGetTicks();
xxx_old = schedparams.next_check;
schedparams.next_check = (unsigned long)LMGetTicks()
+ schedparams.check_interval;
} }
} }
return 0; return 0;
...@@ -508,28 +541,11 @@ PyErr_CheckSignals() ...@@ -508,28 +541,11 @@ PyErr_CheckSignals()
int int
PyOS_InterruptOccurred() PyOS_InterruptOccurred()
{ {
scan_event_queue(1); scan_event_queue(0);
return interrupted; if ( !interrupted )
} return 0;
interrupted = 0;
/* Check whether we are in the foreground */ return 1;
static int
PyMac_InForeground(void)
{
static ProcessSerialNumber ours;
static inited;
ProcessSerialNumber curfg;
Boolean eq;
if ( inited == 0 ) {
(void)GetCurrentProcess(&ours);
inited = 1;
}
if ( GetFrontProcess(&curfg) < 0 )
eq = 1;
else if ( SameProcess(&ours, &curfg, &eq) < 0 )
eq = 1;
return (int)eq;
} }
#endif #endif
...@@ -616,15 +632,6 @@ PyMac_DoYield(int maxsleep, int maycallpython) ...@@ -616,15 +632,6 @@ PyMac_DoYield(int maxsleep, int maycallpython)
static int in_here = 0; static int in_here = 0;
in_here++; in_here++;
/*
** First check for interrupts, if wanted.
** This sets a flag that will be picked up at an appropriate
** moment in the mainloop.
*/
if (schedparams.check_interrupt)
scan_event_queue(0);
/* XXXX Implementing an idle routine goes here */
/* /*
** Check which of the eventloop cases we have: ** Check which of the eventloop cases we have:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment