From 439eaa9f749ab7168e99fce5c867434d28951946 Mon Sep 17 00:00:00 2001 From: Jack Jansen Date: Sat, 10 Nov 2001 00:41:43 +0000 Subject: 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. --- Mac/Python/macglue.c | 97 ++++++++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/Mac/Python/macglue.c b/Mac/Python/macglue.c index 13dbbe7..2789fef 100644 --- a/Mac/Python/macglue.c +++ b/Mac/Python/macglue.c @@ -298,12 +298,21 @@ PyMac_GUSISpin(spin_msg msg, long arg) SpinCursor(msg == SP_AUTO_SPIN ? short(arg) : 1); #endif - if (interrupted) return -1; if ( msg == SP_AUTO_SPIN ) maxsleep = 0; - if ( msg==SP_SLEEP||msg==SP_SELECT ) + if ( msg==SP_SLEEP||msg==SP_SELECT ) { 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? */ @@ -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 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 -scan_event_queue(flush) - int flush; +scan_event_queue(force) + int force; { #if !TARGET_API_MAC_OS8 + if ( interrupted || (!schedparams.check_interrupt && !force) ) + return; if ( CheckEventQueueForUserCancel() ) interrupted = 1; #else register EvQElPtr q; + if ( interrupted || (!schedparams.check_interrupt && !force) || !PyMac_InForeground() ) + return; q = (EvQElPtr) LMGetEventQueue()->qHead; for (; q; q = (EvQElPtr)q->qLink) { @@ -488,18 +517,22 @@ scan_event_queue(flush) int PyErr_CheckSignals() { + int xxx, xxx_old; + if (schedparams.enabled) { - if ( (unsigned long)LMGetTicks() > schedparams.next_check ) { - if ( PyMac_Yield() < 0) - return -1; - schedparams.next_check = (unsigned long)LMGetTicks() - + schedparams.check_interval; + if ( interrupted || (unsigned long)LMGetTicks() > schedparams.next_check ) { + scan_event_queue(0); if (interrupted) { - scan_event_queue(1); /* Eat events up to cmd-. */ interrupted = 0; PyErr_SetNone(PyExc_KeyboardInterrupt); 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; @@ -508,28 +541,11 @@ PyErr_CheckSignals() int PyOS_InterruptOccurred() { - scan_event_queue(1); - return interrupted; -} - -/* 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; + scan_event_queue(0); + if ( !interrupted ) + return 0; + interrupted = 0; + return 1; } #endif @@ -616,15 +632,6 @@ PyMac_DoYield(int maxsleep, int maycallpython) static int in_here = 0; 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: -- cgit v0.12