[pypy-commit] pypy winconsoleio: Added global sigint event

andrewjlawrence pypy.commits at gmail.com
Sun Sep 1 16:44:18 EDT 2019


Author: andrewjlawrence
Branch: winconsoleio
Changeset: r97366:a8914535a9cb
Date: 2019-09-01 21:42 +0100
http://bitbucket.org/pypy/pypy/changeset/a8914535a9cb/

Log:	Added global sigint event

diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py
--- a/pypy/module/__pypy__/test/test_signal.py
+++ b/pypy/module/__pypy__/test/test_signal.py
@@ -12,6 +12,14 @@
             pass
         # assert did not crash
 
+class AppTestSigIntEvent:
+    spaceconfig = dict(usemodules=['__pypy__', 'signal'])
+
+    def test_sigint_event(self):
+        if sys.platform == 'win32':
+            pytest.skip("sigint event only on windows!")
+        import signal
+        
 
 class AppTestThreadSignal(GenericTestThread):
     spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time'])
diff --git a/pypy/module/_io/interp_win32consoleio.py b/pypy/module/_io/interp_win32consoleio.py
--- a/pypy/module/_io/interp_win32consoleio.py
+++ b/pypy/module/_io/interp_win32consoleio.py
@@ -6,16 +6,19 @@
     TypeDef, generic_new_descr, GetSetProperty)
 from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
 from pypy.module._io.interp_iobase import (W_RawIOBase, DEFAULT_BUFFER_SIZE)
+#from pypy.module.signal
 from pypy.interpreter.unicodehelper import fsdecode
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rlib._os_support import _preferred_traits
 from rpython.rlib import rwin32
 from rpython.rlib.rwin32file import make_win32_traits
+from rpython.rtyper.tool import rffi_platform as platform
 
 import unicodedata
 
 SMALLBUF = 4
 BUFMAX = (32*1024*1024)
+BUFSIZ = platform.ConstantInteger("BUFSIZ")
 
 def err_closed(space):
     raise oefmt(space.w_ValueError,
@@ -26,7 +29,6 @@
     raise oefmt(space.w_ValueError,
                 "I/O operation on closed file")
 
-
 def read_console_w(handle, maxlen, readlen):
     err = 0
     sig = 0
@@ -37,8 +39,22 @@
         
         off = 0
         while off < maxlen:
-            n = rffi.cast(rwin32.DWORD, -1)
-            len = m
+            with lltype.scoped_alloc(rwin32.LPDWORD.TO, -1) as n:
+                len = min(maxlen - off, BUFSIZE)
+                rwin32.SetLastError_saved(0)
+                #res = rwin32.ReadConsoleW(handle, buf[off], len, n, rffi.NULL)
+                err = rwin32.GetLastError_saved()
+                if not res:
+                    break
+                    
+                if n == -1 and err == rwin32.ERROR_OPERATION_ABORTED:
+                    break
+                    
+                if n == 0:
+                    if err != rwin32.ERROR_OPERATION_ABORTED:
+                        break
+                    err = 0
+                    #hInterruptEvent
     finally:
         lltype.free(buf, flavor='raw')
         
diff --git a/pypy/module/signal/__init__.py b/pypy/module/signal/__init__.py
--- a/pypy/module/signal/__init__.py
+++ b/pypy/module/signal/__init__.py
@@ -1,6 +1,7 @@
 from pypy.interpreter.mixedmodule import MixedModule
 
 import os
+import sys
 
 class Module(MixedModule):
     applevel_name = '_signal'
@@ -35,6 +36,9 @@
         interpleveldefs['SIG_BLOCK'] = 'space.wrap(interp_signal.SIG_BLOCK)'
         interpleveldefs['SIG_UNBLOCK'] = 'space.wrap(interp_signal.SIG_UNBLOCK)'
         interpleveldefs['SIG_SETMASK'] = 'space.wrap(interp_signal.SIG_SETMASK)'
+        
+    if sys.platform == 'win32':
+        interpleveldefs['sigintevent'] = 'interp_signal.sigintevent'
 
     appleveldefs = {
     }
@@ -63,6 +67,8 @@
         else:
             space.actionflag.__class__ = interp_signal.SignalActionFlag
         # xxx yes I know the previous line is a hack
+        if sys.platform == 'win32':
+            interp_signal.create_sigint_event()
 
     def startup(self, space):
         space.check_signal_action.startup(space)
diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py
--- a/pypy/module/signal/interp_signal.py
+++ b/pypy/module/signal/interp_signal.py
@@ -16,10 +16,12 @@
 from rpython.rlib.rarithmetic import intmask, widen
 from rpython.rlib.rsignal import *
 from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rlib import rwin32
 
+WIN32 = os.name == "nt"
 
-WIN32 = sys.platform == 'win32'
-
+if WIN32:
+   _sigint_event = rwin32.INVALID_HANDLE_VALUE
 
 class SignalActionFlag(AbstractActionFlag):
     # This class uses the C-level pypysig_counter variable as the tick
@@ -148,6 +150,9 @@
     ec = space.getexecutioncontext()
     w_frame = ec.gettopframe_nohidden()
     space.call_function(w_handler, space.newint(n), w_frame)
+    if WIN32:
+        if n == SIGINT:
+            rwin32.SetEvent(_sigint_event)
 
 
 @unwrap_spec(signum=int)
@@ -427,3 +432,15 @@
             # if signals was unblocked, signal handlers have been called
             space.getexecutioncontext().checksignals()
             return _sigset_to_signals(space, previous)
+
+def create_sigint_event():
+    _sigint_event = rwin32.CreateEvent(rffi.NULL, \
+                                       rffi.cast(lltype.Signed, True), \
+                                       rffi.cast(lltype.Signed, False), \
+                                       rffi.NULL)
+
+def sigintevent(space):
+    if _sigint_event == rwin32.INVALID_HANDLE_VALUE:
+        return space.newint(-1)
+    else:
+        return space.newint(_sigint_event)
\ No newline at end of file
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -577,8 +577,13 @@
         'GetNumberOfConsoleInputEvents', [HANDLE, LPDWORD], BOOL)
 
     ERROR_INSUFFICIENT_BUFFER = 122
+    ERROR_OPERATION_ABORTED   = 995
     CP_UTF8 = 65001 
     WideCharToMultiByte = winexternal(
         'WideCharToMultiByte', [rffi.UINT, DWORD, rffi.CWCHARP, rffi.INT,
                                 LPSTR, rffi.INT, rffi.CCHARP, LPBOOL], rffi.INT,
         save_err=rffi.RFFI_SAVE_LASTERROR)
+  
+    ReadConsoleW = winexternal(
+        'ReadConsoleW', [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID], BOOL,
+        save_err=rffi.RFFI_SAVE_LASTERROR)


More information about the pypy-commit mailing list