summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>2001-11-10 00:41:43 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>2001-11-10 00:41:43 (GMT)
commit439eaa9f749ab7168e99fce5c867434d28951946 (patch)
treec8e6dcfb4fc10b432c940b269666e1e6494a38b2
parent94ead57dc3c4f1e3def90bae22bcf24786548af9 (diff)
downloadcpython-439eaa9f749ab7168e99fce5c867434d28951946.zip
cpython-439eaa9f749ab7168e99fce5c867434d28951946.tar.gz
cpython-439eaa9f749ab7168e99fce5c867434d28951946.tar.bz2
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.
-rw-r--r--Mac/Python/macglue.c97
1 files 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: