Ejemplo n.º 1
0
static void maybe_write(struct thread *thread)
{
    obj_t *fp = thread->fp;
    int fd = fixnum_value(fp[-9]);
    int nfound, res;
    obj_t *old_sp;

    nfound = output_writable(fd);
    if (nfound < 0) {
        if (errno != EINTR) {
            old_sp = pop_linkage(thread);
            thread->sp = old_sp + 2;
            old_sp[0] = obj_False;
            old_sp[1] = make_fixnum(errno);
            do_return(thread, old_sp, old_sp);
        } else {
            wait_for_output(thread, fd, maybe_write);
        }
    } else if (nfound == 0)
        wait_for_output(thread, fd, maybe_write);
    else {
                res = write(fd,
                    buffer_data(fp[-8]) + fixnum_value(fp[-7]),
                    fixnum_value(fp[-6]));
                results(thread, pop_linkage(thread), res, make_fixnum(res));
    }
}
Ejemplo n.º 2
0
static void check_fds(bool block)
{
    fd_set readfds, writefds;
    int nfound, fd;
    struct timeval tv, *tvp;

    if (NumFds == 0) {
        if (block) {
          sigset_t set;
          sigemptyset(&set);
          sigsuspend(&set);
        }
        return;
    }

    memcpy(&readfds, &Readers.fds, sizeof(readfds));
    memcpy(&writefds, &Writers.fds, sizeof(writefds));

#ifdef WIN32
    do {
            for (fd = 0; fd < NumFds; fd++) {
            if (FD_ISSET(fd, &Readers.fds) && input_available(fd)) {
                event_broadcast(Readers.events[fd]);
                FD_CLR(fd, &Readers.fds);
                block = 0;
            }
            if (FD_ISSET(fd, &Writers.fds) && output_writable(fd)) {
                event_broadcast(Writers.events[fd]);
                FD_CLR(fd, &Writers.fds);
                block = 0;
            }
        }
    } while (block);
    for (fd = NumFds - 1; fd >= 0; fd--)   /* Adjust NumFds */
        if (FD_ISSET(fd, &Readers.fds) || FD_ISSET(fd, &Writers.fds))
            break;
    NumFds = fd+1;
#else
    if (block)
        tvp = NULL;
    else {
        tv.tv_usec = 0;
        tv.tv_sec = 0;
        tvp = &tv;
    }

    nfound = select(NumFds, &readfds, &writefds, NULL, tvp);

    if (nfound < 0) {
        switch (errno) {
          case EBADF:
            /* One of the file descriptors when bad.  Wake everyone up */
            /* and let the individual threads figure out who is selecting */
            /* on a bogus fd. */
            for (fd = 0; fd < NumFds; fd++) {
                if (FD_ISSET(fd, &Readers.fds))
                    event_broadcast(Readers.events[fd]);
                if (FD_ISSET(fd, &Writers.fds))
                    event_broadcast(Writers.events[fd]);
            }
            FD_ZERO(&Readers.fds);
            FD_ZERO(&Writers.fds);
            NumFds = 0;
            break;

          case EINTR:
            break;
          case EINVAL:
            lose("select failed with EINVAL?");
        }
    }
    else if (nfound > 0) {
        for (fd = 0; fd < NumFds; fd++) {
            if (FD_ISSET(fd, &readfds)) {
                event_broadcast(Readers.events[fd]);
                FD_CLR(fd, &Readers.fds);
            }
            if (FD_ISSET(fd, &writefds)) {
                event_broadcast(Writers.events[fd]);
                FD_CLR(fd, &Writers.fds);
            }
        }
        for (fd = NumFds - 1; fd >= 0; fd--)
            if (FD_ISSET(fd, &Readers.fds) || FD_ISSET(fd, &Writers.fds))
                break;
        NumFds = fd+1;
    }
#endif
}