[Python-checkins] cpython (merge default -> default): Merged

tim.golden python-checkins at python.org
Fri Jun 29 23:14:58 CEST 2012


http://hg.python.org/cpython/rev/5b01f64a71df
changeset:   77865:5b01f64a71df
parent:      77857:e295bf5e42c0
parent:      77862:c01eabd1b36e
user:        Tim Golden <mail at timgolden.me.uk>
date:        Fri Jun 29 22:12:39 2012 +0100
summary:
  Merged

files:
  Parser/myreadline.c |  45 ++++++++++++++++----------------
  1 files changed, 22 insertions(+), 23 deletions(-)


diff --git a/Parser/myreadline.c b/Parser/myreadline.c
--- a/Parser/myreadline.c
+++ b/Parser/myreadline.c
@@ -35,6 +35,9 @@
 static int
 my_fgets(char *buf, int len, FILE *fp)
 {
+#ifdef MS_WINDOWS
+    HANDLE hInterruptEvent;
+#endif
     char *p;
     int err;
     while (1) {
@@ -50,32 +53,28 @@
             return 0; /* No error */
         err = errno;
 #ifdef MS_WINDOWS
-        /* In the case of a Ctrl+C or some other external event
-           interrupting the operation:
-           Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32
-           error code (and feof() returns TRUE).
-           Win9x: Ctrl+C seems to have no effect on fgets() returning
-           early - the signal handler is called, but the fgets()
-           only returns "normally" (ie, when Enter hit or feof())
+        /* Ctrl-C anywhere on the line or Ctrl-Z if the only character
+           on a line will set ERROR_OPERATION_ABORTED. Under normal
+           circumstances Ctrl-C will also have caused the SIGINT handler
+           to fire which will have set the event object returned by
+           _PyOS_SigintEvent. This signal fires in another thread and
+           is not guaranteed to have occurred before this point in the
+           code.
+
+           Therefore: check whether the event is set with a small timeout.
+           If it is, assume this is a Ctrl-C and reset the event. If it
+           isn't set assume that this is a Ctrl-Z on its own and drop
+           through to check for EOF.
         */
         if (GetLastError()==ERROR_OPERATION_ABORTED) {
-            /* Signals come asynchronously, so we sleep a brief
-               moment before checking if the handler has been
-               triggered (we cant just return 1 before the
-               signal handler has been called, as the later
-               signal may be treated as a separate interrupt).
-            */
-            Sleep(1);
-            if (PyOS_InterruptOccurred()) {
+            hInterruptEvent = _PyOS_SigintEvent();
+            switch (WaitForSingleObject(hInterruptEvent, 10)) {
+            case WAIT_OBJECT_0:
+                ResetEvent(hInterruptEvent);
                 return 1; /* Interrupt */
+            case WAIT_FAILED:
+                return -2; /* Error */
             }
-            /* Either the sleep wasn't long enough (need a
-               short loop retrying?) or not interrupted at all
-               (in which case we should revisit the whole thing!)
-               Logging some warning would be nice.  assert is not
-               viable as under the debugger, the various dialogs
-               mean the condition is not true.
-            */
         }
 #endif /* MS_WINDOWS */
         if (feof(fp)) {
@@ -94,7 +93,7 @@
 #endif
             if (s < 0)
                     return 1;
-	    /* try again */
+        /* try again */
             continue;
         }
 #endif

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list