]> granicus.if.org Git - python/commitdiff
Fixed various problems with command-dot handling (some very old):
authorJack Jansen <jack.jansen@cwi.nl>
Sat, 10 Nov 2001 00:41:43 +0000 (00:41 +0000)
committerJack Jansen <jack.jansen@cwi.nl>
Sat, 10 Nov 2001 00:41:43 +0000 (00:41 +0000)
- 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

index 13dbbe7f344ed07c329c0b8bd0379550d33b58ea..2789fef61d763140632903d61d3d8df036aff223 100644 (file)
@@ -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: