Beispiel #1
0
 def _select(self, for_writing):
     """Returns 0 when reading/writing is possible,
     1 when timing out and -1 on error."""
     timeout = self.timeout
     if timeout <= 0.0 or self.fd == _c.INVALID_SOCKET:
         # blocking I/O or no socket.
         return 0
     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 = rffi.make(_c.fd_set)
     rffi.setintfield(fds, 'c_fd_count', 1)
     fds.c_fd_array[0] = rffi.cast(_c.socketfd_type, self.fd)
     null = lltype.nullptr(_c.fd_set)
     if for_writing:
         n = _c.select(self.fd + 1, null, fds, null, tv)
     else:
         n = _c.select(self.fd + 1, fds, null, null, tv)
     lltype.free(fds, flavor='raw')
     lltype.free(tv, flavor='raw')
     if n < 0:
         return -1
     if n == 0:
         return 1
     return 0
Beispiel #2
0
 def _select(self, for_writing):
     """Returns 0 when reading/writing is possible,
     1 when timing out and -1 on error."""
     timeout = self.timeout
     if timeout <= 0.0 or self.fd == _c.INVALID_SOCKET:
         # blocking I/O or no socket.
         return 0
     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)
     null = lltype.nullptr(_c.fd_set.TO)
     if for_writing:
         n = _c.select(self.fd + 1, null, fds, null, tv)
     else:
         n = _c.select(self.fd + 1, fds, null, null, tv)
     lltype.free(fds, flavor='raw')
     lltype.free(tv, flavor='raw')
     if n < 0:
         return -1
     if n == 0:
         return 1
     return 0
Beispiel #3
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 = lltype.malloc(_c.timeval, flavor="raw")
        frac = math.fmod(timeout, 1.0)
        ll_timeval.c_tv_sec = int(timeout)
        ll_timeval.c_tv_usec = int((timeout - int(timeout)) * 1000000.0)
    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")
Beispiel #4
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')
Beispiel #5
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')
Beispiel #6
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)
Beispiel #7
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)
Beispiel #8
0
def select(space, w_iwtd, w_owtd, w_ewtd, w_timeout=None):
    """Wait until one or more file descriptors are ready for some kind of I/O.
The first three arguments are sequences of file descriptors to be waited for:
rlist -- wait until ready for reading
wlist -- wait until ready for writing
xlist -- wait for an ``exceptional condition''
If only one kind of condition is required, pass [] for the other lists.
A file descriptor is either a socket or file object, or a small integer
gotten from a fileno() method call on one of those.

The optional 4th argument specifies a timeout in seconds; it may be
a floating point number to specify fractions of seconds.  If it is absent
or None, the call will never time out.

The return value is a tuple of three lists corresponding to the first three
arguments; each contains the subset of the corresponding file descriptors
that are ready.

*** IMPORTANT NOTICE ***
On Windows, only sockets are supported; on Unix, all file descriptors.
"""

    iwtd_w = space.listview(w_iwtd)
    owtd_w = space.listview(w_owtd)
    ewtd_w = space.listview(w_ewtd)

    ll_inl  = lltype.nullptr(_c.fd_set.TO)
    ll_outl = lltype.nullptr(_c.fd_set.TO)
    ll_errl = lltype.nullptr(_c.fd_set.TO)
    ll_timeval = lltype.nullptr(_c.timeval)
    
    try:
        fdlistin  = None
        fdlistout = None
        fdlisterr = None
        nfds = -1
        if len(iwtd_w) > 0:
            ll_inl = lltype.malloc(_c.fd_set.TO, flavor='raw')
            fdlistin, nfds = _build_fd_set(space, iwtd_w, ll_inl, nfds)
        if len(owtd_w) > 0:
            ll_outl = lltype.malloc(_c.fd_set.TO, flavor='raw')
            fdlistout, nfds = _build_fd_set(space, owtd_w, ll_outl, nfds)
        if len(ewtd_w) > 0:
            ll_errl = lltype.malloc(_c.fd_set.TO, flavor='raw')
            fdlisterr, nfds = _build_fd_set(space, ewtd_w, ll_errl, nfds)

        if space.is_w(w_timeout, space.w_None):
            timeout = -1.0
        else:
            timeout = space.float_w(w_timeout)
        if timeout >= 0.0:
            ll_timeval = rffi.make(_c.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:
            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)
    finally:
        if ll_timeval: lltype.free(ll_timeval, flavor='raw')
        if ll_errl:    lltype.free(ll_errl, flavor='raw')
        if ll_outl:    lltype.free(ll_outl, flavor='raw')
        if ll_inl:     lltype.free(ll_inl, flavor='raw')

    return space.newtuple([space.newlist(resin_w),
                           space.newlist(resout_w),
                           space.newlist(reserr_w)])