/* * void init_netio(void) * * Input: None * Output: None * Side Effects: This is a needed exported function which will * be called to initialise the network loop code. */ void init_netio(void) { sigio_signal = SIGRTMIN; pfds = MyMalloc(MAXCONNECTIONS * sizeof(struct pollfd)); index_to_fde = MyMalloc(MAXCONNECTIONS * sizeof(fde_t *)); mask_our_signal(sigio_signal); }
/* * void init_netio(void) * * Input: None * Output: None * Side Effects: This is a needed exported function which will * be called to initialise the network loop code. */ void init_netio(void) { int fd; sigio_signal = SIGRTMIN; for (fd = 0; fd < MAXCONNECTIONS; fd++) { pollfd_list.pollfds[fd].fd = -1; } pollfd_list.maxindex = 0; mask_our_signal(sigio_signal); }
/* * void init_netio(void) * * Input: None * Output: None * Side Effects: This is a needed exported function which will * be called to initialise the network loop code. */ void init_netio(void) { int fd; my_pid = getpid(); for (fd = 0; fd < HARD_FDLIMIT; fd++) pollfd_list.pollfds[fd].fd = -1; pollfd_list.maxindex = 0; mask_our_signal(SIGIO_SIGNAL); }
/* * init_netio * * This is a needed exported function which will be called to initialise * the network loop code. */ void init_netio(void) { int fd; pollfd_list.pollfds = MyMalloc(maxconnections * sizeof(struct pollfd)); for (fd = 0; fd < maxconnections; fd++) { pollfd_list.pollfds[fd].fd = -1; } pollfd_list.maxindex = 0; sigio_signal = SIGRTMIN; sigio_is_screwed = 1; /* Start off with poll first.. */ mask_our_signal(sigio_signal); }
/* int comm_select(unsigned long delay) * Input: The maximum time to delay. * Output: Returns -1 on error, 0 on success. * Side-effects: Deregisters future interest in IO and calls the handlers * if an event occurs for an FD. * Comments: Check all connections for new connections and input data * that is to be processed. Also check for connections with data queued * and whether we can write it out. * Called to do the new-style IO, courtesy of of squid (like most of this * new IO code). This routine handles the stuff we've hidden in * comm_setselect and fd_table[] and calls callbacks for IO ready * events. */ int comm_select(unsigned long delay) { int num = 0; int revents = 0; int sig; int fd; int ci; PF *hdl; fde_t *F; struct siginfo si; struct timespec timeout; timeout.tv_sec = 0; timeout.tv_nsec = 1000000 * delay; for (;;) { if (!sigio_is_screwed) { if ((sig = sigtimedwait(&our_sigset, &si, &timeout)) > 0) { if (sig == SIGIO) { ilog(L_WARN, "Kernel RT Signal queue overflowed. Is /proc/sys/kernel/rtsig-max too small?"); sigio_is_screwed = 1; break; } fd = si.si_fd; pollfd_list.pollfds[fd].revents |= si.si_band; revents = pollfd_list.pollfds[fd].revents; num++; F = &fd_table[fd]; set_time(); if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) { callbacks_called++; hdl = F->read_handler; F->read_handler = NULL; poll_update_pollfds(fd, POLLIN, NULL); if (hdl) hdl(fd, F->read_data); } if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) { callbacks_called++; hdl = F->write_handler; F->write_handler = NULL; poll_update_pollfds(fd, POLLOUT, NULL); if (hdl) hdl(fd, F->write_data); } } else break; } else break; } if (!sigio_is_screwed) /* We don't need to proceed */ { set_time(); return 0; } for (;;) { if (sigio_is_screwed) { signal(sigio_signal, SIG_IGN); signal(sigio_signal, SIG_DFL); sigio_is_screwed = 0; } num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, 0); if (num >= 0) break; if (ignoreErrno(errno)) continue; /* error! */ set_time(); return -1; /* NOTREACHED */ } /* update current time again, eww.. */ set_time(); if (num == 0) return 0; /* XXX we *could* optimise by falling out after doing num fds ... */ for (ci = 0; ci < pollfd_list.maxindex + 1; ci++) { if (((revents = pollfd_list.pollfds[ci].revents) == 0) || (pollfd_list.pollfds[ci].fd) == -1) continue; fd = pollfd_list.pollfds[ci].fd; F = &fd_table[fd]; if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) { callbacks_called++; hdl = F->read_handler; F->read_handler = NULL; poll_update_pollfds(fd, POLLIN, NULL); if (hdl) hdl(fd, F->read_data); } if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) { callbacks_called++; hdl = F->write_handler; F->write_handler = NULL; poll_update_pollfds(fd, POLLOUT, NULL); if (hdl) hdl(fd, F->write_data); } } mask_our_signal(sigio_signal); return 0; }
/* void comm_select(unsigned long delay) * Input: The maximum time to delay. * Output: None * Side-effects: Deregisters future interest in IO and calls the handlers * if an event occurs for an FD. * Comments: Check all connections for new connections and input data * that is to be processed. Also check for connections with data queued * and whether we can write it out. * Called to do the new-style IO, courtesy of squid (like most of this * new IO code). This routine handles the stuff we've hidden in * comm_setselect and fd_table[] and calls callbacks for IO ready * events. */ void comm_select(unsigned long delay) { int revents = 0, sig, fd; PF *hdl; fde_t *F; struct siginfo si; struct timespec timeout; timeout.tv_sec = 0; timeout.tv_nsec = 1000000 * delay; sig = sigtimedwait(&our_sigset, &si, &timeout); set_time(); if (sig != SIGIO) { if (sig > 0) { fd = si.si_fd; pollfd_list.pollfds[fd].revents |= si.si_band; revents = pollfd_list.pollfds[fd].revents; F = &fd_table[fd]; if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) { hdl = F->read_handler; F->read_handler = NULL; poll_update_pollfds(fd, POLLIN, NULL); if (hdl) hdl(fd, F->read_data); } if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) { hdl = F->write_handler; F->write_handler = NULL; poll_update_pollfds(fd, POLLOUT, NULL); if (hdl) hdl(fd, F->write_data); } } return; } /* RT signal queue overflowed.. */ if (CurrentTime - last_rtsigqo_warning >= 30) { ilog(L_WARN, "Kernel RT Signal queue overflowed. " "Is /proc/sys/kernel/rtsig-max too small?"); last_rtsigqo_warning = CurrentTime; } signal(SIGIO_SIGNAL, SIG_IGN); signal(SIGIO_SIGNAL, SIG_DFL); /* ..try polling instead */ { int num, ci; while ((num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, 0)) < 0 && ignoreErrno(errno)) ; /* update current time again, eww.. */ set_time(); if (num > 0) { /* XXX we *could* optimise by falling out after doing num fds ... */ for (ci = 0; ci < pollfd_list.maxindex + 1; ci++) { if (((revents = pollfd_list.pollfds[ci].revents) == 0) || (pollfd_list.pollfds[ci].fd) == -1) continue; fd = pollfd_list.pollfds[ci].fd; F = &fd_table[fd]; if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) { hdl = F->read_handler; F->read_handler = NULL; poll_update_pollfds(fd, POLLIN, NULL); if (hdl) hdl(fd, F->read_data); } if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) { hdl = F->write_handler; F->write_handler = NULL; poll_update_pollfds(fd, POLLOUT, NULL); if (hdl) hdl(fd, F->write_data); } } } } mask_our_signal(SIGIO_SIGNAL); }