[pypy-commit] pypy winoverlapped: Add _overlapped.py

andrewjlawrence pypy.commits at gmail.com
Fri Feb 8 04:57:57 EST 2019


Author: andrewjlawrence
Branch: winoverlapped
Changeset: r95887:293f10f71a75
Date: 2019-02-06 13:19 +0000
http://bitbucket.org/pypy/pypy/changeset/293f10f71a75/

Log:	Add _overlapped.py

diff --git a/lib_pypy/_overlapped.py b/lib_pypy/_overlapped.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_overlapped.py
@@ -0,0 +1,97 @@
+"""
+Support routines for overlapping io.
+Currently, this extension module is only required when using the
+modules on Windows.
+"""
+
+import sys
+if sys.platform != 'win32':
+    raise ImportError("The '_winapi' module is only available on Windows")
+
+# Declare external Win32 functions
+
+from _pypy_winbase_cffi import ffi as _ffi
+_kernel32 = _ffi.dlopen('kernel32')
+
+GetVersion = _kernel32.GetVersion
+NULL = _ffi.NULL
+
+class Overlapped(object):
+    def __init__(self, handle):
+        self.overlapped = _ffi.new('OVERLAPPED[1]')
+        self.handle = handle
+        self.readbuffer = None
+        self.pending = 0
+        self.completed = 0
+        self.writebuffer = None
+        self.overlapped[0].hEvent = \
+                _kernel32.CreateEventW(NULL, True, False, NULL)
+
+    def __del__(self):
+        # do this somehow else
+        xxx
+        err = _kernel32.GetLastError()
+        bytes = _ffi.new('DWORD[1]')
+        o = overlapped[0]
+        if overlapped[0].pending:
+            if _kernel32.CancelIoEx(o.handle, o.overlapped) & \
+                self.GetOverlappedResult(o.handle, o.overlapped, _ffi.addressof(bytes), True):
+                # The operation is no longer pending, nothing to do
+                pass
+            else:
+                raise RuntimeError('deleting an overlapped struct with a pending operation not supported')
+
+    @property
+    def event(self):
+        return None
+
+    def GetOverlappedResult(self, wait):
+        transferred = _ffi.new('DWORD[1]', [0])
+        res = _kernel32.GetOverlappedResult(self.handle, self.overlapped, transferred, wait != 0)
+        if res:
+            err = ERROR_SUCCESS
+        else:
+            err = GetLastError()
+        if err in (ERROR_SUCCESS, ERROR_MORE_DATA, ERROR_OPERATION_ABORTED):
+            self.completed = 1
+            self.pending = 0
+        elif res == ERROR_IO_INCOMPLETE:
+            pass
+        else:
+            self.pending = 0
+            raise _WinError()
+        if self.completed and self.read_buffer:
+            if transferred != len(self.read_buffer):
+                raise _WinError()
+        return transferred[0], err
+
+    def getbuffer(self):
+        xxx
+        return None
+
+    def cancel(self):
+        xxx
+        return None
+
+ 
+def ConnectNamedPipe(handle, overlapped=False):
+    if overlapped:
+        ov = Overlapped(handle)
+    else:
+        ov = Overlapped(None)
+    success = _kernel32.ConnectNamedPipe(handle, ov.overlapped)
+    if overlapped:
+        # Overlapped ConnectNamedPipe never returns a success code
+        assert success == 0
+        err = _kernel32.GetLastError()
+        if err == ERROR_IO_PENDING:
+            ov.pending = 1
+        elif err == ERROR_PIPE_CONNECTED:
+            _kernel32.SetEvent(ov.overlapped[0].hEvent)
+        else:
+            del ov
+            raise _WinError()
+        return ov
+    elif not success:
+        raise _WinError()
+
diff --git a/lib_pypy/_winapi.py b/lib_pypy/_winapi.py
--- a/lib_pypy/_winapi.py
+++ b/lib_pypy/_winapi.py
@@ -89,7 +89,7 @@
                 # The operation is no longer pending, nothing to do
                 pass
             else:
-                raise RuntimeError('deleting an overlapped strucwith a pending operation not supported')
+                raise RuntimeError('deleting an overlapped struct with a pending operation not supported')
 
     @property
     def event(self):


More information about the pypy-commit mailing list