int rb_select_select(long delay) { int num; int fd; PF *hdl; rb_fde_t *F; struct timeval to; /* Copy over the read/write sets so we don't have to rebuild em */ memcpy(&tmpreadfds, &select_readfds, sizeof(fd_set)); memcpy(&tmpwritefds, &select_writefds, sizeof(fd_set)); for (;;) { to.tv_sec = 0; to.tv_usec = delay * 1000; num = select(rb_maxfd + 1, &tmpreadfds, &tmpwritefds, NULL, &to); if (num >= 0) break; if (rb_ignore_errno(errno)) continue; rb_set_time(); /* error! */ return -1; /* NOTREACHED */ } rb_set_time(); if (num == 0) return 0; /* XXX we *could* optimise by falling out after doing num fds ... */ for (fd = 0; fd < rb_maxfd + 1; fd++) { F = rb_find_fd(fd); if (F == NULL) continue; if (FD_ISSET(fd, &tmpreadfds)) { hdl = F->read_handler; F->read_handler = NULL; if (hdl) hdl(F, F->read_data); } if (!IsFDOpen(F)) continue; /* Read handler closed us..go on */ if (FD_ISSET(fd, &tmpwritefds)) { hdl = F->write_handler; F->write_handler = NULL; if (hdl) hdl(F, F->write_data); } if (F->read_handler == NULL) select_update_selectfds(F, RB_SELECT_READ, NULL); if (F->write_handler == NULL) select_update_selectfds(F, RB_SELECT_WRITE, NULL); } return 0; }
/* * rb_setselect * * This is a needed exported function which will be called to register * and deregister interest in a pending IO state for a given FD. */ void rb_setselect_select(rb_fde_t *F, unsigned int type, PF * handler, void *client_data) { lrb_assert(IsFDOpen(F)); if (type & RB_SELECT_READ) { F->read_handler = handler; F->read_data = client_data; select_update_selectfds(F, RB_SELECT_READ, handler); } if (type & RB_SELECT_WRITE) { F->write_handler = handler; F->write_data = client_data; select_update_selectfds(F, RB_SELECT_WRITE, handler); } }
/* * comm_setselect * * This is a needed exported function which will be called to register * and deregister interest in a pending IO state for a given FD. */ void comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler, void *client_data, time_t timeout) { fde_t *F = &fd_table[fd]; s_assert(fd >= 0); s_assert(F->flags.open); if(type & COMM_SELECT_READ) { F->read_handler = handler; F->read_data = client_data; select_update_selectfds(fd, COMM_SELECT_READ, handler); } if(type & COMM_SELECT_WRITE) { F->write_handler = handler; F->write_data = client_data; select_update_selectfds(fd, COMM_SELECT_WRITE, handler); } if(timeout) F->timeout = CurrentTime + (timeout / 1000); }
int comm_select(unsigned long delay) { int num; int fd; PF *hdl; fde_t *F; struct timeval to; /* Copy over the read/write sets so we don't have to rebuild em */ memcpy(&tmpreadfds, &select_readfds, sizeof(fd_set)); memcpy(&tmpwritefds, &select_writefds, sizeof(fd_set)); for (;;) { to.tv_sec = 0; to.tv_usec = delay * 1000; num = select(highest_fd + 1, &tmpreadfds, &tmpwritefds, NULL, &to); if(num >= 0) break; if(ignoreErrno(errno)) continue; set_time(); /* error! */ return -1; /* NOTREACHED */ } set_time(); if(num == 0) return 0; /* XXX we *could* optimise by falling out after doing num fds ... */ for (fd = 0; fd < highest_fd + 1; fd++) { F = &fd_table[fd]; if(FD_ISSET(fd, &tmpreadfds)) { hdl = F->read_handler; F->read_handler = NULL; if(hdl) hdl(fd, F->read_data); } if(F->flags.open == 0) continue; /* Read handler closed us..go on */ if(FD_ISSET(fd, &tmpwritefds)) { hdl = F->write_handler; F->write_handler = NULL; if(hdl) hdl(fd, F->write_data); } if(F->read_handler == NULL) select_update_selectfds(fd, COMM_SELECT_READ, NULL); if(F->write_handler == NULL) select_update_selectfds(fd, COMM_SELECT_WRITE, NULL); } return 0; }