[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