virtual int add_interest()

in io/epoll.cpp [118:170]


    virtual int add_interest(Event e) override {
        if (e.fd < 0)
            LOG_ERROR_RETURN(EINVAL, -1, "invalid file descriptor ", e.fd);
        if (unlikely(!e.interests))
            return 0;
        if (unlikely((size_t)e.fd >= _inflight_events.size()))
            _inflight_events.resize(e.fd * 2);

        e.interests &= EVENT_RWEO;
        auto& entry = _inflight_events[e.fd];
        auto eint = entry.interests & EVENT_RWEO;
        int op;
        if (!eint) {
            eint = e.interests;
            op = EPOLL_CTL_ADD;
        } else {
            if ((eint ^ e.interests) & ONE_SHOT)
                LOG_ERROR_RETURN(EALREADY, -1, "conflicted ONE_SHOT flag");
            auto intersection = e.interests & eint;
            auto data = (entry.reader_data != e.data) * EVENT_READ  |
                        (entry.writer_data != e.data) * EVENT_WRITE |
                        (entry.error_data  != e.data) * EVENT_ERROR ;
            if (intersection & data)
                LOG_ERROR_RETURN(EALREADY, -1, "conflicted interest(s)");

            eint |= e.interests;
            op = EPOLL_CTL_MOD;
        }

        auto events = evmap.translate_bitwisely(eint);
        if (likely(eint & ONE_SHOT)) {
            events |= EPOLLONESHOT;
            if (likely(op == EPOLL_CTL_MOD)) {
                // This may falsely fail with errno == ENOENT,
                // if the fd was closed and created again.
                // We should suppress that specific error log
                int ret = ctl(e.fd, op, events, ENOENT);
                if (likely(ret == 0)) goto ok;
                // in such cases, and `EPOLL_CTL_ADD` it again.
                else if (ret > 0) op = EPOLL_CTL_ADD;
                else /*if (ret < 0)*/ goto fail;
            }
        }
        if (ctl(e.fd, op, events) < 0) { fail:
            LOG_ERROR_RETURN(0, -1, "failed to add_interest()");
        }

ok:     entry.interests |= eint;
        if (e.interests & EVENT_READ)  entry.reader_data = e.data;
        if (e.interests & EVENT_WRITE) entry.writer_data = e.data;
        if (e.interests & EVENT_ERROR) entry.error_data  = e.data;
        return 0;
    }