[pypy-svn] r42111 - pypy/dist/pypy/rlib

afa at codespeak.net afa at codespeak.net
Tue Apr 17 01:50:15 CEST 2007


Author: afa
Date: Tue Apr 17 01:50:15 2007
New Revision: 42111

Modified:
   pypy/dist/pypy/rlib/_rsocket_ctypes.py
   pypy/dist/pypy/rlib/rsocket.py
Log:
rsocket progress on Windows: implement timeouts and _select()


Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py
==============================================================================
--- pypy/dist/pypy/rlib/_rsocket_ctypes.py	(original)
+++ pypy/dist/pypy/rlib/_rsocket_ctypes.py	Tue Apr 17 01:50:15 2007
@@ -7,7 +7,8 @@
 from pypy.rpython.rctypes.aerrno import geterrno
 
 from ctypes import c_ushort, c_int, c_uint, c_char_p, c_void_p, c_char, c_ubyte
-from ctypes import c_short, POINTER, ARRAY, cdll, sizeof, SetPointerType
+from ctypes import c_short, c_long, c_ulong
+from ctypes import POINTER, ARRAY, cdll, sizeof, SetPointerType
 from pypy.rlib.rarithmetic import intmask, r_uint
 
 # Also not used here, but exported for other code.
@@ -52,12 +53,14 @@
 class CConfig:
     _header_ = HEADER + COND_HEADER
     # constants
+    linux      = ctypes_platform.Defined('linux')
+    MS_WINDOWS = ctypes_platform.Defined('_WIN32')
+
     O_NONBLOCK = ctypes_platform.DefinedConstantInteger('O_NONBLOCK')
     F_GETFL = ctypes_platform.DefinedConstantInteger('F_GETFL')
     F_SETFL = ctypes_platform.DefinedConstantInteger('F_SETFL')
+    FIONBIO = ctypes_platform.DefinedConstantInteger('FIONBIO')
 
-    linux      = ctypes_platform.Defined('linux')
-    MS_WINDOWS = ctypes_platform.Defined('_WIN32')
     INVALID_SOCKET = ctypes_platform.DefinedConstantInteger('INVALID_SOCKET')
     INET_ADDRSTRLEN = ctypes_platform.DefinedConstantInteger('INET_ADDRSTRLEN')
     INET6_ADDRSTRLEN= ctypes_platform.DefinedConstantInteger('INET6_ADDRSTRLEN')
@@ -237,6 +240,13 @@
                                              ('events', c_short),
                                              ('revents', c_short)])
 
+CConfig.timeval = ctypes_platform.Struct('struct timeval',
+                                         [('tv_sec', c_long),
+                                          ('tv_usec', c_long)])
+CConfig.fd_set = ctypes_platform.Struct('struct fd_set',
+                                         [('fd_count', c_uint),
+                                          ('fd_array', c_uint * 64)]) # XXX FD_SETSIZE
+
 if _MS_WINDOWS:
     CConfig.WSAData = ctypes_platform.Struct('struct WSAData',
                                      [('wVersion', c_ushort),
@@ -279,6 +289,7 @@
 O_NONBLOCK = cConfig.O_NONBLOCK
 F_GETFL = cConfig.F_GETFL
 F_SETFL = cConfig.F_SETFL
+FIONBIO = cConfig.FIONBIO
 INET_ADDRSTRLEN = cConfig.INET_ADDRSTRLEN
 INET6_ADDRSTRLEN = cConfig.INET6_ADDRSTRLEN
 POLLIN = cConfig.POLLIN
@@ -293,7 +304,7 @@
 
 if MS_WINDOWS:
     def invalid_socket(fd):
-        return fd == INVALID_SOCKET
+        return c_uint(fd).value == INVALID_SOCKET
     INVALID_SOCKET = cConfig.INVALID_SOCKET
 else:
     def invalid_socket(fd):
@@ -319,6 +330,8 @@
 if _POSIX:
     nfds_t = cConfig.nfds_t
     pollfd = cConfig.pollfd
+timeval = cConfig.timeval
+fd_set = cConfig.fd_set
 
 c_int_size = sizeof(c_int)
 SetPointerType(addrinfo_ptr, addrinfo)
@@ -517,6 +530,12 @@
     socketpair.argtypes = [c_int, c_int, c_int, POINTER(socketpair_t)]
     socketpair.restype = c_int
 
+if _MS_WINDOWS:
+    ioctlsocket = socketdll.ioctlsocket
+    ioctlsocket.argtypes = [c_int, c_long, POINTER(c_ulong)]
+    ioctlsocket.restype = c_int
+    
+
 shutdown = socketdll.shutdown
 shutdown.argtypes = [c_int, c_int]
 shutdown.restype = c_int
@@ -525,6 +544,11 @@
     poll = socketdll.poll
     poll.argtypes = [POINTER(pollfd), nfds_t, c_int]
     poll.restype = c_int
+select = socketdll.select
+select.argtypes = [c_int,
+                   POINTER(fd_set), POINTER(fd_set), POINTER(fd_set),
+                   POINTER(timeval)]
+select.restype = c_int
 
 if MS_WINDOWS:
     WSAData = cConfig.WSAData

Modified: pypy/dist/pypy/rlib/rsocket.py
==============================================================================
--- pypy/dist/pypy/rlib/rsocket.py	(original)
+++ pypy/dist/pypy/rlib/rsocket.py	Tue Apr 17 01:50:15 2007
@@ -13,8 +13,8 @@
 
 from pypy.rlib.objectmodel import instantiate
 from pypy.rlib import _rsocket_ctypes as _c
-from ctypes import cast, POINTER, c_char, c_char_p, pointer, byref, c_void_p
-from ctypes import create_string_buffer, sizeof, cast
+from ctypes import c_char, c_ulong, c_char_p, c_void_p
+from ctypes import POINTER, pointer, byref, create_string_buffer, sizeof, cast
 from pypy.rpython.rctypes.astruct import offsetof
 from pypy.rlib.rarithmetic import intmask
 
@@ -471,35 +471,62 @@
     def __del__(self):
         self.close()
 
-    def _setblocking(self, block):
-        # PLAT various methods on other platforms
-        # XXX Windows missing
-        delay_flag = _c.fcntl(self.fd, _c.F_GETFL, 0)
-        if block:
-            delay_flag &= ~_c.O_NONBLOCK
-        else:
-            delay_flag |= _c.O_NONBLOCK
-        _c.fcntl(self.fd, _c.F_SETFL, delay_flag)
-
-    def _select(self, for_writing):
-        """Returns 0 when reading/writing is possible,
-        1 when timing out and -1 on error."""
-        if self.timeout <= 0.0 or self.fd < 0:
-            # blocking I/O or no socket.
+    if hasattr(_c, 'fcntl'):
+        def _setblocking(self, block):
+            delay_flag = _c.fcntl(self.fd, _c.F_GETFL, 0)
+            if block:
+                delay_flag &= ~_c.O_NONBLOCK
+            else:
+                delay_flag |= _c.O_NONBLOCK
+            _c.fcntl(self.fd, _c.F_SETFL, delay_flag)
+    elif hasattr(_c, 'ioctlsocket'):
+        def _setblocking(self, block):
+            flag = c_ulong(not block)
+            _c.ioctlsocket(self.fd, _c.FIONBIO, byref(flag))
+
+    if hasattr(_c, 'poll'):
+        def _select(self, for_writing):
+            """Returns 0 when reading/writing is possible,
+            1 when timing out and -1 on error."""
+            if self.timeout <= 0.0 or self.fd < 0:
+                # blocking I/O or no socket.
+                return 0
+            pollfd = _c.pollfd()
+            pollfd.fd = self.fd
+            if for_writing:
+                pollfd.events = _c.POLLOUT
+            else:
+                pollfd.events = _c.POLLIN
+            timeout = int(self.timeout * 1000.0 + 0.5)
+            n = _c.poll(byref(pollfd), 1, timeout)
+            if n < 0:
+                return -1
+            if n == 0:
+                return 1
             return 0
-        pollfd = _c.pollfd()
-        pollfd.fd = self.fd
-        if for_writing:
-            pollfd.events = _c.POLLOUT
-        else:
-            pollfd.events = _c.POLLIN
-        timeout = int(self.timeout * 1000.0 + 0.5)
-        n = _c.poll(byref(pollfd), 1, timeout)
-        if n < 0:
-            return -1
-        if n == 0:
-            return 1
-        return 0
+    else:
+        # Version witout poll(): use select()
+        def _select(self, for_writing):
+            """Returns 0 when reading/writing is possible,
+            1 when timing out and -1 on error."""
+            if self.timeout <= 0.0 or self.fd < 0:
+                # blocking I/O or no socket.
+                return 0
+            tv = _c.timeval(tv_sec=int(self.timeout),
+                            tv_usec=int((self.timeout-int(self.timeout))
+                                        * 1000000))
+            fds = _c.fd_set(fd_count=1)
+            fds.fd_array[0] = self.fd
+            if for_writing:
+                n = _c.select(self.fd + 1, None, byref(fds), None, byref(tv))
+            else:
+                n = _c.select(self.fd + 1, byref(fds), None, None, byref(tv))
+            if n < 0:
+                return -1
+            if n == 0:
+                return 1
+            return 0
+        
         
     def error_handler(self):
         return last_error()



More information about the Pypy-commit mailing list