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] fd = rffi.cast(lltype.Signed, pollfd.c_fd) revents = rffi.cast(lltype.Signed, pollfd.c_revents) if revents: retval.append((fd, revents)) finally: lltype.free(pollfds, flavor='raw') return retval
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 == _c.INVALID_SOCKET: # blocking I/O or no socket. return 0 pollfd = rffi.make(_c.pollfd) try: rffi.setintfield(pollfd, 'c_fd', self.fd) if for_writing: rffi.setintfield(pollfd, 'c_events', _c.POLLOUT) else: rffi.setintfield(pollfd, 'c_events', _c.POLLIN) timeout = int(self.timeout * 1000.0 + 0.5) n = _c.poll(rffi.cast(lltype.Ptr(_c.pollfdarray), pollfd), 1, timeout) finally: lltype.free(pollfd, flavor='raw') if n < 0: return -1 if n == 0: return 1 return 0