Пример #1
0
 def READ(self, size):
     from rpython.rlib._rsocket_rffi import socketrecv, geterrno
     with rffi.scoped_alloc_buffer(size) as buf:
         length = socketrecv(self.fd, buf.raw, buf.size, 0)
         if length < 0:
             raise WindowsError(geterrno(), "recv")
         return buf.str(length)
Пример #2
0
 def READ(self, size):
     from rpython.rlib._rsocket_rffi import socketrecv, geterrno
     with rffi.scoped_alloc_buffer(size) as buf:
         length = socketrecv(self.fd, buf.raw, buf.size, 0)
         if length < 0:
             raise WindowsError(geterrno(), "recv")
         return buf.str(length)
Пример #3
0
    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 getWindowsError(space):
    errno = geterrno()
    message = rwin32.FormatErrorW(errno)
    w_errcode = space.newint(errno)
    return OperationError(space.w_WindowsError,
                         space.newtuple([w_errcode, space.newtext(*message),
                        space.w_None, w_errcode]))
Пример #5
0
def _call_select(space, iwtd_w, owtd_w, ewtd_w, ll_inl, ll_outl, ll_errl, ll_timeval):
    fdlistin = fdlistout = fdlisterr = None
    nfds = -1
    if ll_inl:
        fdlistin, nfds = _build_fd_set(space, iwtd_w, ll_inl, nfds)
    if ll_outl:
        fdlistout, nfds = _build_fd_set(space, owtd_w, ll_outl, nfds)
    if ll_errl:
        fdlisterr, nfds = _build_fd_set(space, ewtd_w, ll_errl, nfds)

    res = _c.select(nfds + 1, ll_inl, ll_outl, ll_errl, ll_timeval)

    if res < 0:
        errno = _c.geterrno()
        msg = _c.socket_strerror_str(errno)
        w_errortype = space.fromcache(Cache).w_error
        raise OperationError(w_errortype, space.newtuple([space.wrap(errno), space.wrap(msg)]))

    resin_w = []
    resout_w = []
    reserr_w = []
    if res > 0:
        if fdlistin is not None:
            _unbuild_fd_set(space, iwtd_w, fdlistin, ll_inl, resin_w)
        if fdlistout is not None:
            _unbuild_fd_set(space, owtd_w, fdlistout, ll_outl, resout_w)
        if fdlisterr is not None:
            _unbuild_fd_set(space, ewtd_w, fdlisterr, ll_errl, reserr_w)
    return space.newtuple([space.newlist(resin_w), space.newlist(resout_w), space.newlist(reserr_w)])
Пример #6
0
def _call_select(space, iwtd_w, owtd_w, ewtd_w,
                 ll_inl, ll_outl, ll_errl, ll_timeval):
    fdlistin = fdlistout = fdlisterr = None
    nfds = -1
    if ll_inl:
        fdlistin, nfds = _build_fd_set(space, iwtd_w, ll_inl, nfds)
    if ll_outl:
        fdlistout, nfds = _build_fd_set(space, owtd_w, ll_outl, nfds)
    if ll_errl:
        fdlisterr, nfds = _build_fd_set(space, ewtd_w, ll_errl, nfds)

    res = _c.select(nfds + 1, ll_inl, ll_outl, ll_errl, ll_timeval)

    if res < 0:
        errno = _c.geterrno()
        msg = _c.socket_strerror_str(errno)
        w_errortype = space.fromcache(Cache).w_error
        raise OperationError(w_errortype, space.newtuple([
            space.newint(errno), space.newtext(msg)]))

    resin_w = []
    resout_w = []
    reserr_w = []
    if res > 0:
        if fdlistin is not None:
            _unbuild_fd_set(space, iwtd_w, fdlistin,  ll_inl,  resin_w)
        if fdlistout is not None:
            _unbuild_fd_set(space, owtd_w, fdlistout, ll_outl, resout_w)
        if fdlisterr is not None:
            _unbuild_fd_set(space, ewtd_w, fdlisterr, ll_errl, reserr_w)
    return space.newtuple([space.newlist(resin_w),
                           space.newlist(resout_w),
                           space.newlist(reserr_w)])
Пример #7
0
    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
Пример #8
0
        def _connect(self, address):
            """Connect the socket to a remote address."""
            addr = address.lock()
            res = _c.socketconnect(self.fd, addr, address.addrlen)
            address.unlock()
            errno = _c.geterrno()
            timeout = self.timeout
            if timeout > 0.0 and res < 0 and errno == _c.EWOULDBLOCK:
                tv = rffi.make(_c.timeval)
                rffi.setintfield(tv, 'c_tv_sec', int(timeout))
                rffi.setintfield(tv, 'c_tv_usec',
                                 int((timeout-int(timeout)) * 1000000))
                fds = lltype.malloc(_c.fd_set.TO, flavor='raw')
                _c.FD_ZERO(fds)
                _c.FD_SET(self.fd, fds)
                fds_exc = lltype.malloc(_c.fd_set.TO, flavor='raw')
                _c.FD_ZERO(fds_exc)
                _c.FD_SET(self.fd, fds_exc)
                null = lltype.nullptr(_c.fd_set.TO)

                try:
                    n = _c.select(self.fd + 1, null, fds, fds_exc, tv)

                    if n > 0:
                        if _c.FD_ISSET(self.fd, fds):
                            # socket writable == connected
                            return (0, False)
                        else:
                            # per MS docs, call getsockopt() to get error
                            assert _c.FD_ISSET(self.fd, fds_exc)
                            return (self.getsockopt_int(_c.SOL_SOCKET,
                                                        _c.SO_ERROR), False)
                    elif n == 0:
                        return (_c.EWOULDBLOCK, True)
                    else:
                        return (_c.geterrno(), False)

                finally:
                    lltype.free(fds, flavor='raw')
                    lltype.free(fds_exc, flavor='raw')
                    lltype.free(tv, flavor='raw')

            if res == 0:
                errno = 0
            return (errno, False)
Пример #9
0
        def _connect(self, address):
            """Connect the socket to a remote address."""
            addr = address.lock()
            res = _c.socketconnect(self.fd, addr, address.addrlen)
            address.unlock()
            errno = _c.geterrno()
            timeout = self.timeout
            if timeout > 0.0 and res < 0 and errno == _c.EWOULDBLOCK:
                tv = rffi.make(_c.timeval)
                rffi.setintfield(tv, 'c_tv_sec', int(timeout))
                rffi.setintfield(tv, 'c_tv_usec',
                                 int((timeout-int(timeout)) * 1000000))
                fds = lltype.malloc(_c.fd_set.TO, flavor='raw')
                _c.FD_ZERO(fds)
                _c.FD_SET(self.fd, fds)
                fds_exc = lltype.malloc(_c.fd_set.TO, flavor='raw')
                _c.FD_ZERO(fds_exc)
                _c.FD_SET(self.fd, fds_exc)
                null = lltype.nullptr(_c.fd_set.TO)

                try:
                    n = _c.select(self.fd + 1, null, fds, fds_exc, tv)

                    if n > 0:
                        if _c.FD_ISSET(self.fd, fds):
                            # socket writable == connected
                            return (0, False)
                        else:
                            # per MS docs, call getsockopt() to get error
                            assert _c.FD_ISSET(self.fd, fds_exc)
                            return (self.getsockopt_int(_c.SOL_SOCKET,
                                                        _c.SO_ERROR), False)
                    elif n == 0:
                        return (_c.EWOULDBLOCK, True)
                    else:
                        return (_c.geterrno(), False)

                finally:
                    lltype.free(fds, flavor='raw')
                    lltype.free(fds_exc, flavor='raw')
                    lltype.free(tv, flavor='raw')

            if res == 0:
                errno = 0
            return (errno, False)
Пример #10
0
def select(inl, outl, excl, timeout=-1.0):
    nfds = 0
    if inl: 
        ll_inl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_inl)
        for i in inl:
            _c.FD_SET(i, ll_inl)
            if i > nfds:
                nfds = i
    else:
        ll_inl = lltype.nullptr(_c.fd_set.TO)
    if outl: 
        ll_outl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_outl)
        for i in outl:
            _c.FD_SET(i, ll_outl)
            if i > nfds:
                nfds = i
    else:
        ll_outl = lltype.nullptr(_c.fd_set.TO)
    if excl: 
        ll_excl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_excl)
        for i in excl:
            _c.FD_SET(i, ll_excl)
            if i > nfds:
                nfds = i
    else:
        ll_excl = lltype.nullptr(_c.fd_set.TO)
    if timeout != -1.0:
        ll_timeval = rffi.make(_c.timeval)
        rffi.setintfield(ll_timeval, 'c_tv_sec', int(timeout))
        rffi.setintfield(ll_timeval, 'c_tv_usec', int((timeout-int(timeout))
                                                  * 1000000))
    else:
        ll_timeval = lltype.nullptr(_c.timeval)
    try:
        res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval)
        if res == -1:
            raise SelectError(_c.geterrno())
        if res == 0:
            return ([], [], [])
        else:
            return (
                [i for i in inl if _c.FD_ISSET(i, ll_inl)],
                [i for i in outl if _c.FD_ISSET(i, ll_outl)],
                [i for i in excl if _c.FD_ISSET(i, ll_excl)])
    finally:
        if ll_inl:
            lltype.free(ll_inl, flavor='raw')
        if ll_outl:
            lltype.free(ll_outl, flavor='raw')
        if ll_excl:
            lltype.free(ll_excl, flavor='raw')
        if ll_timeval:
            lltype.free(ll_timeval, flavor='raw')
Пример #11
0
def _call_select(space, iwtd_w, owtd_w, ewtd_w, ll_inl, ll_outl, ll_errl,
                 ll_timeval, timeout):
    fdlistin = fdlistout = fdlisterr = None
    nfds = -1
    if ll_inl:
        fdlistin, nfds = _build_fd_set(space, iwtd_w, ll_inl, nfds)
    if ll_outl:
        fdlistout, nfds = _build_fd_set(space, owtd_w, ll_outl, nfds)
    if ll_errl:
        fdlisterr, nfds = _build_fd_set(space, ewtd_w, ll_errl, nfds)

    if ll_timeval:
        end_time = timeutils.monotonic(space) + timeout
    else:
        end_time = 0.0

    while True:
        if ll_timeval:
            i = int(timeout)
            rffi.setintfield(ll_timeval, 'c_tv_sec', i)
            rffi.setintfield(ll_timeval, 'c_tv_usec',
                             int((timeout - i) * 1000000))

        res = _c.select(nfds + 1, ll_inl, ll_outl, ll_errl, ll_timeval)

        if res >= 0:
            break  # normal path
        err = _c.geterrno()
        if err != errno.EINTR:
            msg = _c.socket_strerror_unicode(err)
            raise OperationError(
                space.w_OSError,
                space.newtuple([space.newint(err),
                                space.newunicode(msg)]))
        # got EINTR, automatic retry
        space.getexecutioncontext().checksignals()
        if timeout > 0.0:
            timeout = end_time - timeutils.monotonic(space)
            if timeout < 0.0:
                timeout = 0.0

    resin_w = []
    resout_w = []
    reserr_w = []
    if res > 0:
        if fdlistin is not None:
            _unbuild_fd_set(space, iwtd_w, fdlistin, ll_inl, resin_w)
        if fdlistout is not None:
            _unbuild_fd_set(space, owtd_w, fdlistout, ll_outl, resout_w)
        if fdlisterr is not None:
            _unbuild_fd_set(space, ewtd_w, fdlisterr, ll_errl, reserr_w)
    return space.newtuple([
        space.newlist(resin_w),
        space.newlist(resout_w),
        space.newlist(reserr_w)
    ])
Пример #12
0
        def _connect(self, address):
            """Connect the socket to a remote address."""
            addr = address.lock()
            res = _c.socketconnect(self.fd, addr, address.addrlen)
            address.unlock()
            errno = _c.geterrno()
            if self.timeout > 0.0 and res < 0 and errno == _c.EINPROGRESS:
                timeout = self._select(True)
                if timeout == 0:
                    res = self.getsockopt_int(_c.SOL_SOCKET, _c.SO_ERROR)
                    if res == _c.EISCONN:
                        res = 0
                    errno = res
                elif timeout == -1:
                    return (_c.geterrno(), False)
                else:
                    return (_c.EWOULDBLOCK, True)

            if res < 0:
                res = errno
            return (res, False)
Пример #13
0
        def _connect(self, address):
            """Connect the socket to a remote address."""
            addr = address.lock()
            res = _c.socketconnect(self.fd, addr, address.addrlen)
            address.unlock()
            errno = _c.geterrno()
            if self.timeout > 0.0 and res < 0 and errno == _c.EINPROGRESS:
                timeout = self._select(True)
                if timeout == 0:
                    res = self.getsockopt_int(_c.SOL_SOCKET, _c.SO_ERROR)
                    if res == _c.EISCONN:
                        res = 0
                    errno = res
                elif timeout == -1:
                    return (_c.geterrno(), False)
                else:
                    return (_c.EWOULDBLOCK, True)

            if res < 0:
                res = errno
            return (res, False)
Пример #14
0
def last_error():
    return CSocketError(_c.geterrno())
Пример #15
0
 def WRITE(self, data):
     from rpython.rlib._rsocket_rffi import send, geterrno
     length = send(self.fd, data, len(data), 0)
     if length < 0:
         raise WindowsError(geterrno(), "send")
     return length
Пример #16
0
def last_error():
    return CSocketError(_c.geterrno())
Пример #17
0
 def WRITE(self, data):
     from rpython.rlib._rsocket_rffi import send, geterrno
     length = send(self.fd, data, len(data), 0)
     if length < 0:
         raise WindowsError(geterrno(), "send")
     return length
Пример #18
0
def select(inl, outl, excl, timeout=-1.0, handle_eintr=False):
    nfds = 0
    if inl:
        ll_inl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_inl)
        for i in inl:
            _c.FD_SET(i, ll_inl)
            if i > nfds:
                nfds = i
    else:
        ll_inl = lltype.nullptr(_c.fd_set.TO)
    if outl:
        ll_outl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_outl)
        for i in outl:
            _c.FD_SET(i, ll_outl)
            if i > nfds:
                nfds = i
    else:
        ll_outl = lltype.nullptr(_c.fd_set.TO)
    if excl:
        ll_excl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_excl)
        for i in excl:
            _c.FD_SET(i, ll_excl)
            if i > nfds:
                nfds = i
    else:
        ll_excl = lltype.nullptr(_c.fd_set.TO)

    if timeout < 0:
        ll_timeval = lltype.nullptr(_c.timeval)
        while True:
            res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval)
            if not handle_eintr or res >= 0 or _c.geterrno() != EINTR:
                break
    else:
        sec = int(timeout)
        usec = int((timeout - sec) * 10**6)
        ll_timeval = rffi.make(_c.timeval)
        rffi.setintfield(ll_timeval, 'c_tv_sec', sec)
        rffi.setintfield(ll_timeval, 'c_tv_usec', usec)
        res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval)
        if handle_eintr and res < 0 and _c.geterrno() == EINTR:
            res = 0  # interrupted, act as timed out
    try:
        if res == -1:
            raise SelectError(_c.geterrno())
        if res == 0:
            return ([], [], [])
        else:
            return ([i for i in inl if _c.FD_ISSET(i, ll_inl)
                     ], [i for i in outl if _c.FD_ISSET(i, ll_outl)],
                    [i for i in excl if _c.FD_ISSET(i, ll_excl)])
    finally:
        if ll_inl:
            lltype.free(ll_inl, flavor='raw')
        if ll_outl:
            lltype.free(ll_outl, flavor='raw')
        if ll_excl:
            lltype.free(ll_excl, flavor='raw')
        if ll_timeval:
            lltype.free(ll_timeval, flavor='raw')
Пример #19
0
    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()
                if _c.WSAEventSelect(fd, event, wsaEvents) != 0:
                    raise PollError(_c.geterrno())

                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 == r_uint(_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 fd, event in eventdict.iteritems():
                _c.WSAEventSelect(fd, event, 0)
                _c.WSACloseEvent(event)
            lltype.free(socketevents, flavor='raw')

        return retval
Пример #20
0
    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()
                if _c.WSAEventSelect(fd, event, wsaEvents) != 0:
                    raise PollError(_c.geterrno())

                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

            # XXX does not correctly report write status of a port
            ret = _c.WSAWaitForMultipleEvents(numevents, socketevents, False,
                                              timeout, False)

            if ret == _c.WSA_WAIT_TIMEOUT:
                return []

            if ret == r_uint(_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 fd, event in eventdict.iteritems():
                _c.WSAEventSelect(fd, event, 0)
                _c.WSACloseEvent(event)
            lltype.free(socketevents, flavor='raw')

        return retval
Пример #21
0
def select(inl, outl, excl, timeout=-1.0, handle_eintr=False):
    nfds = 0
    if inl:
        ll_inl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_inl)
        for i in inl:
            _c.FD_SET(i, ll_inl)
            if i > nfds:
                nfds = i
    else:
        ll_inl = lltype.nullptr(_c.fd_set.TO)
    if outl:
        ll_outl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_outl)
        for i in outl:
            _c.FD_SET(i, ll_outl)
            if i > nfds:
                nfds = i
    else:
        ll_outl = lltype.nullptr(_c.fd_set.TO)
    if excl:
        ll_excl = lltype.malloc(_c.fd_set.TO, flavor='raw')
        _c.FD_ZERO(ll_excl)
        for i in excl:
            _c.FD_SET(i, ll_excl)
            if i > nfds:
                nfds = i
    else:
        ll_excl = lltype.nullptr(_c.fd_set.TO)

    if timeout < 0:
        ll_timeval = lltype.nullptr(_c.timeval)
        while True:
            res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval)
            if not handle_eintr or res >= 0 or _c.geterrno() != EINTR:
                break
    else:
        sec = int(timeout)
        usec = int((timeout - sec) * 10**6)
        ll_timeval = rffi.make(_c.timeval)
        rffi.setintfield(ll_timeval, 'c_tv_sec', sec)
        rffi.setintfield(ll_timeval, 'c_tv_usec', usec)
        res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval)
        if handle_eintr and res < 0 and _c.geterrno() == EINTR:
            res = 0  # interrupted, act as timed out
    try:
        if res == -1:
            raise SelectError(_c.geterrno())
        if res == 0:
            return ([], [], [])
        else:
            return (
                [i for i in inl if _c.FD_ISSET(i, ll_inl)],
                [i for i in outl if _c.FD_ISSET(i, ll_outl)],
                [i for i in excl if _c.FD_ISSET(i, ll_excl)])
    finally:
        if ll_inl:
            lltype.free(ll_inl, flavor='raw')
        if ll_outl:
            lltype.free(ll_outl, flavor='raw')
        if ll_excl:
            lltype.free(ll_excl, flavor='raw')
        if ll_timeval:
            lltype.free(ll_timeval, flavor='raw')