[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