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)); } }
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 }