[pypy-svn] r46831 - in pypy/dist/pypy: rlib rpython/lltypesystem
arigo at codespeak.net
arigo at codespeak.net
Sat Sep 22 18:40:19 CEST 2007
Author: arigo
Date: Sat Sep 22 18:40:18 2007
New Revision: 46831
Modified:
pypy/dist/pypy/rlib/_rsocket_rffi.py
pypy/dist/pypy/rlib/rpoll.py
pypy/dist/pypy/rpython/lltypesystem/rffi.py
Log:
poll() for Windows. All this code comes from module/select/interp_select,
ported to rffi.
The test doesn't pass, but I don't feel like debugging it.
It fails in a call to accept() but only if poll() was called
previously on that socket... no clue. Needs Windows expertise.
Modified: pypy/dist/pypy/rlib/_rsocket_rffi.py
==============================================================================
--- pypy/dist/pypy/rlib/_rsocket_rffi.py (original)
+++ pypy/dist/pypy/rlib/_rsocket_rffi.py Sat Sep 22 18:40:18 2007
@@ -490,28 +490,28 @@
[rffi.INT, lltype.Ptr(fd_set), lltype.Ptr(fd_set),
lltype.Ptr(fd_set), lltype.Ptr(timeval)],
rffi.INT)
-
- ##WSACreateEvent = socketdll.WSACreateEvent
- ##WSACreateEvent.argtypes = []
- ##WSACreateEvent.restype = WSAEVENT
-
- ##WSACloseEvent = socketdll.WSACloseEvent
- ##WSACloseEvent.argtypes = [WSAEVENT]
- ##WSACloseEvent.restype = c_int
-
- ##WSAEventSelect = socketdll.WSAEventSelect
- ##WSAEventSelect.argtypes = [socketfd_type, WSAEVENT, rffi.LONG]
- ##WSAEventSelect.restype = c_int
-
- ##WSAWaitForMultipleEvents = socketdll.WSAWaitForMultipleEvents
- ##WSAWaitForMultipleEvents.argtypes = [rffi.LONG, POINTER(WSAEVENT),
- ## c_int, rffi.LONG, c_int]
- ##WSAWaitForMultipleEvents.restype = c_long
-
- ##WSAEnumNetworkEvents = socketdll.WSAEnumNetworkEvents
- ##WSAEnumNetworkEvents.argtypes = [socketfd_type, WSAEVENT,
- ## POINTER(WSANETWORKEVENTS)]
- ##WSAEnumNetworkEvents.restype = c_int
+ #
+ # The following is for pypy.rlib.rpoll
+ #
+ WSAEVENT_ARRAY = rffi.CArray(WSAEVENT)
+
+ WSACreateEvent = external('WSACreateEvent', [], WSAEVENT)
+
+ WSACloseEvent = external('WSACloseEvent', [WSAEVENT], rffi.INT)
+
+ WSAEventSelect = external('WSAEventSelect',
+ [socketfd_type, WSAEVENT, rffi.LONG],
+ rffi.INT)
+
+ WSAWaitForMultipleEvents = external('WSAWaitForMultipleEvents',
+ [rffi.LONG, lltype.Ptr(WSAEVENT_ARRAY),
+ rffi.INT, rffi.LONG, rffi.INT],
+ rffi.ULONG)
+
+ WSAEnumNetworkEvents = external('WSAEnumNetworkEvents',
+ [socketfd_type, WSAEVENT,
+ lltype.Ptr(WSANETWORKEVENTS)],
+ rffi.INT)
if MS_WINDOWS:
WSAData = cConfig.WSAData
Modified: pypy/dist/pypy/rlib/rpoll.py
==============================================================================
--- pypy/dist/pypy/rlib/rpoll.py (original)
+++ pypy/dist/pypy/rlib/rpoll.py Sat Sep 22 18:40:18 2007
@@ -21,41 +21,139 @@
for name in eventnames:
globals()[name] = getattr(_c.cConfig, name)
-# ____________________________________________________________
-# poll()
-#
class PollError(Exception):
def __init__(self, errno):
self.errno = errno
def get_msg(self):
- return os.strerror(self.errno)
+ return _c.socket_strerror_str(self.errno)
+
+# ____________________________________________________________
+# poll() for POSIX systems
+#
+if hasattr(_c, 'poll'):
+
+ def poll(fddict, timeout=-1):
+ """'fddict' maps file descriptors to interesting events.
+ 'timeout' is an integer in milliseconds, and NOT a float
+ number of seconds, but it's the same in CPython. Use -1 for infinite.
+ Returns a list [(fd, events)].
+ """
+ numfd = len(fddict)
+ pollfds = lltype.malloc(_c.pollfdarray, numfd, flavor='raw')
+ try:
+ i = 0
+ for fd, events in fddict.iteritems():
+ rffi.setintfield(pollfds[i], 'c_fd', fd)
+ rffi.setintfield(pollfds[i], 'c_events', events)
+ i += 1
+ assert i == numfd
+
+ ret = _c.poll(pollfds, numfd, timeout)
+
+ if ret < 0:
+ raise PollError(_c.geterrno())
+
+ retval = []
+ for i in range(numfd):
+ pollfd = pollfds[i]
+ if pollfd.c_revents:
+ retval.append((pollfd.c_fd, pollfd.c_revents))
+ finally:
+ lltype.free(pollfds, flavor='raw')
+ return retval
+
+# ____________________________________________________________
+# poll() for Win32
+#
+if hasattr(_c, 'WSAEventSelect'):
+
+ def poll(fddict, timeout=-1):
+ """'fddict' maps file descriptors to interesting events.
+ 'timeout' is an integer in milliseconds, and NOT a float
+ number of seconds, but it's the same in CPython. Use -1 for infinite.
+ Returns a list [(fd, events)].
+ """
+ numfd = len(fddict)
+ numevents = 0
+ socketevents = lltype.malloc(_c.WSAEVENT_ARRAY, numfd, flavor='raw')
+ try:
+ eventdict = {}
+
+ for fd, events in fddict.iteritems():
+ # select desired events
+ wsaEvents = 0
+ if events & _c.POLLIN:
+ wsaEvents |= _c.FD_READ | _c.FD_ACCEPT | _c.FD_CLOSE
+ if events & _c.POLLOUT:
+ wsaEvents |= _c.FD_WRITE | _c.FD_CONNECT | _c.FD_CLOSE
+
+ # if no events then ignore socket
+ if wsaEvents == 0:
+ continue
+
+ # select socket for desired events
+ event = _c.WSACreateEvent()
+ _c.WSAEventSelect(fd, event, wsaEvents)
+
+ eventdict[fd] = event
+ socketevents[numevents] = event
+ numevents += 1
+
+ assert numevents <= numfd
+
+ # if no sockets then return immediately
+ # XXX commented out by arigo - we just want to sleep for
+ # 'timeout' milliseconds in this case, which is what
+ # I hope WSAWaitForMultipleEvents will do, no?
+ #if numevents == 0:
+ # return []
+
+ # prepare timeout
+ if timeout < 0:
+ timeout = _c.INFINITE
+
+ ret = _c.WSAWaitForMultipleEvents(numevents, socketevents,
+ False, timeout, False)
+
+ if ret == _c.WSA_WAIT_TIMEOUT:
+ return []
+
+ if ret == _c.WSA_WAIT_FAILED:
+ raise PollError(_c.geterrno())
+
+ retval = []
+ info = rffi.make(_c.WSANETWORKEVENTS)
+ for fd, event in eventdict.iteritems():
+ if _c.WSAEnumNetworkEvents(fd, event, info) < 0:
+ continue
+ revents = 0
+ if info.c_lNetworkEvents & _c.FD_READ:
+ revents |= _c.POLLIN
+ if info.c_lNetworkEvents & _c.FD_ACCEPT:
+ revents |= _c.POLLIN
+ if info.c_lNetworkEvents & _c.FD_WRITE:
+ revents |= _c.POLLOUT
+ if info.c_lNetworkEvents & _c.FD_CONNECT:
+ if info.c_iErrorCode[_c.FD_CONNECT_BIT]:
+ revents |= _c.POLLERR
+ else:
+ revents |= _c.POLLOUT
+ if info.c_lNetworkEvents & _c.FD_CLOSE:
+ if info.c_iErrorCode[_c.FD_CLOSE_BIT]:
+ revents |= _c.POLLERR
+ else:
+ if fddict[fd] & _c.POLLIN:
+ revents |= _c.POLLIN
+ if fddict[fd] & _c.POLLOUT:
+ revents |= _c.POLLOUT
+ if revents:
+ retval.append((fd, revents))
+
+ lltype.free(info, flavor='raw')
+
+ finally:
+ for i in range(numevents):
+ _c.WSACloseEvent(socketevents[i])
+ lltype.free(socketevents, flavor='raw')
-def poll(fddict, timeout=-1):
- """'fddict' maps file descriptors to interesting events.
- 'timeout' is an integer in milliseconds, and NOT a float
- number of seconds, but it's the same in CPython. Use -1 for infinite.
- Returns a list [(fd, events)].
- """
- numfd = len(fddict)
- pollfds = lltype.malloc(_c.pollfdarray, numfd, flavor='raw')
- try:
- i = 0
- for fd, events in fddict.iteritems():
- rffi.setintfield(pollfds[i], 'c_fd', fd)
- rffi.setintfield(pollfds[i], 'c_events', events)
- i += 1
- assert i == numfd
-
- ret = _c.poll(pollfds, numfd, timeout)
-
- if ret < 0:
- raise PollError(_c.geterrno())
-
- retval = []
- for i in range(numfd):
- pollfd = pollfds[i]
- if pollfd.c_revents:
- retval.append((pollfd.c_fd, pollfd.c_revents))
- finally:
- lltype.free(pollfds, flavor='raw')
- return retval
+ return retval
Modified: pypy/dist/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rffi.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rffi.py Sat Sep 22 18:40:18 2007
@@ -82,8 +82,10 @@
if SOURCE != TARGET:
if TARGET is lltype.Float:
arg = float(arg)
- elif (isinstance(SOURCE, lltype.Number) and
- isinstance(TARGET, lltype.Number)):
+ elif ((isinstance(SOURCE, lltype.Number)
+ or SOURCE is lltype.Bool)
+ and (isinstance(TARGET, lltype.Number)
+ or TARGET is lltype.Bool)):
arg = cast(TARGET, arg)
real_args = real_args + (arg,)
to_free = to_free + (freeme,)
More information about the Pypy-commit
mailing list