[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