Пример #1
0
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();
}