[pypy-commit] pypy winmultiprocessing: First implementation of socket.share. Fixed issue with _testcapi import.

andrewjlawrence pypy.commits at gmail.com
Sun May 19 16:30:40 EDT 2019


Author: andrewjlawrence
Branch: winmultiprocessing
Changeset: r96636:440feb6ea372
Date: 2019-05-19 21:28 +0100
http://bitbucket.org/pypy/pypy/changeset/440feb6ea372/

Log:	First implementation of socket.share. Fixed issue with _testcapi
	import.

diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_pypy_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -64,7 +64,6 @@
 
     compiler = new_compiler()
     compiler.output_dir = output_dir
-
     # Compile .c file
     include_dir = os.path.join(thisdir, '..', 'include')
     if sys.platform == 'win32':
@@ -80,7 +79,7 @@
     output_filename = modulename + _get_c_extension_suffix()
     if sys.platform == 'win32':
         libname = 'python{0[0]}{0[1]}'.format(sys.version_info)
-        library = os.path.join(thisdir, '..', 'lib', libname)
+        library = os.path.join(thisdir, '..', 'libs', libname)
         if not os.path.exists(library + '.lib'):
             # For a local translation or nightly build
             library = os.path.join(thisdir, '..', 'pypy', 'goal', libname)
diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -16,6 +16,7 @@
     GetSetProperty, TypeDef, generic_new_descr, interp_attrproperty,
     make_weakref_descr)
 
+_WIN32 = sys.platform.startswith('win')
 
 # XXX Hack to separate rpython and pypy
 def addr_as_object(addr, fd, space):
@@ -197,13 +198,29 @@
             self.register_finalizer(space)
 
     @unwrap_spec(family=int, type=int, proto=int,
-                 w_fileno=WrappedDefault(None))
+                 w_fdobj=WrappedDefault(None))
     def descr_init(self, space, family=AF_INET, type=SOCK_STREAM, proto=0,
-                   w_fileno=None):
+                   w_fdobj=None):
         try:
-            if not space.is_w(w_fileno, space.w_None):
-                sock = RSocket(family, type, proto,
-                               fd=space.c_filedescriptor_w(w_fileno))
+            if not space.is_w(w_fdobj, space.w_None):
+                if _WIN32 and space.isinstance_w(w_fdobj, space.w_bytes):
+                    from rpython.rlib.rsocket import _c
+                    # it is possible to pass some bytes representing a socket
+                    # in the file descriptor object on winodws
+                    fdobj = space.text_w(w_fdobj)
+                    info_charptr = rffi.str2charp(fdobj)
+                    try:
+                        info_ptr = rffi.cast(lltype.Ptr(_c.WSAPROTOCOL_INFOW), info_charptr)
+                        fd = _c.WSASocketW(_c.FROM_PROTOCOL_INFO, _c.FROM_PROTOCOL_INFO,
+                        _c.FROM_PROTOCOL_INFO, info_ptr, 0, _c.WSA_FLAG_OVERLAPPED)
+                        if fd == rsocket.INVALID_SOCKET:
+                            raise converted_error(space, rsocket.last_error())
+                        sock = RSocket(family, type, proto, fd)
+                    finally:
+                        lltype.free(info_charptr, flavor='raw')
+                else:
+                    sock = RSocket(family, type, proto,
+                                   fd=space.c_filedescriptor_w(w_fdobj))
             else:
                 sock = RSocket(family, type, proto, inheritable=False)
             W_Socket.__init__(self, space, sock)
@@ -757,6 +774,26 @@
         finally:
             lltype.free(recv_ptr, flavor='raw')
 
+    @unwrap_spec(processid=int)
+    def share_w(self, space, processid):
+        from rpython.rtyper.lltypesystem import rffi, lltype
+        from rpython.rlib import rwin32
+        from rpython.rlib.rsocket import _c
+        info_ptr = lltype.malloc(_c.WSAPROTOCOL_INFOW, flavor='raw')
+        try:
+            winprocessid = rffi.cast(rwin32.DWORD, processid)
+            res = _c.WSADuplicateSocketW(
+                        self.sock.fd, winprocessid, info_ptr)
+
+            if res < 0:
+                raise converted_error(space, rsocket.last_error())
+
+            bytes_ptr = rffi.cast(rffi.CCHARP, info_ptr)
+            w_bytes = space.newbytes(rffi.charpsize2str(bytes_ptr, rffi.sizeof(_c.WSAPROTOCOL_INFOW)))
+        finally:
+            lltype.free(info_ptr, flavor='raw')
+        return w_bytes
+			
     @unwrap_spec(how="c_int")
     def shutdown_w(self, space, how):
         """shutdown(flag)
@@ -890,6 +927,7 @@
 """.split()
 if hasattr(rsocket._c, 'WSAIoctl'):
     socketmethodnames.append('ioctl')
+    socketmethodnames.append('share')
 if rsocket._c.HAVE_SENDMSG:
     socketmethodnames.append('sendmsg')
     socketmethodnames.append('recvmsg')
diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py
--- a/pypy/module/_socket/test/test_sock_app.py
+++ b/pypy/module/_socket/test/test_sock_app.py
@@ -574,6 +574,13 @@
         s = _socket.socket()
         raises(ValueError, s.ioctl, -1, None)
         s.ioctl(_socket.SIO_KEEPALIVE_VALS, (1, 100, 100))
+		
+    def test_socket_sharelocal(self):
+        import _socket, sys, os
+        if sys.platform != 'win32':
+            skip("win32 only")
+        assert hasattr(_socket.socket, 'share')
+        s = _socket.socket()
 
     def test_dup(self):
         import _socket as socket, os
diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py
--- a/rpython/rlib/_rsocket_rffi.py
+++ b/rpython/rlib/_rsocket_rffi.py
@@ -203,6 +203,7 @@
 FD_CONNECT_BIT FD_CLOSE_BIT
 WSA_IO_PENDING WSA_IO_INCOMPLETE WSA_INVALID_HANDLE
 WSA_INVALID_PARAMETER WSA_NOT_ENOUGH_MEMORY WSA_OPERATION_ABORTED
+WSA_FLAG_OVERLAPPED
 SIO_RCVALL SIO_KEEPALIVE_VALS
 
 SIOCGIFNAME SIOCGIFINDEX
@@ -1009,6 +1010,7 @@
     CConfig.WSAPROTOCOL_INFO = platform.Struct(
         'WSAPROTOCOL_INFOA',
         [])  # Struct is just passed between functions
+	   
     CConfig.FROM_PROTOCOL_INFO = platform.DefinedConstantInteger(
         'FROM_PROTOCOL_INFO')
 
@@ -1033,6 +1035,45 @@
         [('onoff', rffi.ULONG),
          ('keepalivetime', rffi.ULONG),
          ('keepaliveinterval', rffi.ULONG)])
+	
+    CConfig.GUID = platform.Struct(
+		     'struct _GUID',
+			 [('Data1', rffi.UINT),
+             ('Data2', rffi.UINT),
+             ('Data3', rffi.UINT),
+             ('Data4', rffi.CFixedArray(rffi.UCHAR, 8))
+         ])
+		 
+    CConfig.WSAPROTOCOLCHAIN = platform.Struct(
+        'struct _WSAPROTOCOLCHAIN',
+        [('ChainLen', rffi.INT),
+         ('ChainEntries', rffi.CFixedArray(rffi.UINT, 7))])
+	
+    WSAPROTOCOLCHAIN = CConfig.WSAPROTOCOLCHAIN
+    GUID = CConfig.GUID 
+	
+    CConfig.WSAPROTOCOL_INFOW = platform.Struct(
+        'struct _WSAPROTOCOL_INFOW',
+        [('dwServiceFlags1', rffi.UINT),
+         ('dwServiceFlags2', rffi.UINT),
+         ('dwServiceFlags3', rffi.UINT),
+         ('dwServiceFlags4', rffi.UINT),
+         ('dwProviderFlags', rffi.UINT),
+         ('ProviderId', GUID),
+         ('dwCatalogEntryId', rffi.UINT),
+         ('ProtocolChain', WSAPROTOCOLCHAIN),
+         ('iVersion', rffi.INT),
+         ('iAddressFamily', rffi.INT),
+         ('iMaxSockAddr', rffi.INT),
+         ('iMinSockAddr', rffi.INT),
+         ('iSocketType', rffi.INT),
+         ('iProtocol', rffi.INT),
+         ('iProtocolMaxOffset', rffi.INT),
+         ('iNetworkByteOrder', rffi.INT),
+         ('iSecurityScheme', rffi.INT),
+         ('dwMessageSize', rffi.UINT),
+         ('dwProviderReserved', rffi.UINT),
+         ('szProtocol',  rffi.CFixedArray(rffi.UCHAR, 256))])
 
 
 class cConfig:
@@ -1336,6 +1377,20 @@
                          rffi.VOIDP, rwin32.DWORD,
                          rwin32.LPDWORD, rffi.VOIDP, rffi.VOIDP],
                         rffi.INT, save_err=SAVE_ERR)
+
+    WSAPROTOCOL_INFOW = cConfig.WSAPROTOCOL_INFOW
+
+    WSADuplicateSocketW = external('WSADuplicateSocketW',
+                                 [socketfd_type, rwin32.DWORD,
+                                  lltype.Ptr(WSAPROTOCOL_INFOW)],
+                                  rffi.INT, save_err=SAVE_ERR)
+
+    WSASocketW = external('WSASocketW',
+                         [rffi.INT, rffi.INT, rffi.INT,
+                          lltype.Ptr(WSAPROTOCOL_INFOW),
+                          rwin32.DWORD, rwin32.DWORD],
+                         socketfd_type, save_err=SAVE_ERR)
+								  
     tcp_keepalive = cConfig.tcp_keepalive
 
     WSAPROTOCOL_INFO = cConfig.WSAPROTOCOL_INFO


More information about the pypy-commit mailing list