void PollerSelect::loop_once(Timestamp *ts) { runNextLoopHandlers(); struct timeval timeout; struct timeval *pto = nullptr; if (ts != nullptr) { Timestamp now = Timestamp::now(); if (*ts < now) { timeout = {0, 0}; } else { Timestamp inter = *ts - now; timeout = {.tv_sec = inter.sec(), .tv_usec = inter.usec()}; } pto = &timeout; } fd_set rset = rset_; fd_set wset = wset_; fd_set eset = eset_; int nready = ::select(maxfd_, &rset, &wset, &eset, pto); errorif(nready == -1, "select: %s", ::strerror(errno)); for (int fd = 0; fd < maxfd_ && nready > 0; fd++) { DeferCaller deferCaller([this] { runNextTickHandlers(); }); Channel *ch = getChannel(fd); if (ch == nullptr) continue; bool flag = false; if (FD_ISSET(fd, &eset)) { flag = true; ch->handleErroEvent(); continue; } if (FD_ISSET(fd, &rset)) { flag = true; ch->handleReadEvent(); } if (FD_ISSET(fd, &wset) && (ch = getChannel(fd)) != nullptr) { flag = true; ch->handleWritEvent(); } if (flag == true) { nready--; } } runAfterLoopHandlers(); }