예제 #1
0
int SelectPoll::unregisterFd(SOCKET_FD fd)
{
    KUMA_INFOTRACE("SelectPoll::unregisterFd, fd="<<fd);
    int max_fd = int(poll_items_.size() - 1);
    if (fd < 0 || fd > max_fd) {
        KUMA_WARNTRACE("SelectPoll::unregisterFd, failed, max_fd=" << max_fd);
        return KUMA_ERROR_INVALID_PARAM;
    }
    updateFdSet(fd, 0);
    int idx = poll_items_[fd].idx;
    if (fd == max_fd) {
        poll_items_.pop_back();
    } else {
        poll_items_[fd].fd = INVALID_FD;
        poll_items_[fd].cb = nullptr;
        poll_items_[fd].idx = -1;
    }
    int last_idx = int(poll_fds_.size() - 1);
    if (idx > last_idx || -1 == idx) {
        return KUMA_ERROR_NOERR;
    }
    if (idx != last_idx) {
        std::iter_swap(poll_fds_.begin() + idx, poll_fds_.end() - 1);
        poll_items_[poll_fds_[idx].fd].idx = idx;
    }
    poll_fds_.pop_back();
    return KUMA_ERROR_NOERR;
}
예제 #2
0
void SelectPoll::updateFdSet(SOCKET_FD fd, uint32_t events)
{
    if(events != 0) {
        if (events & KUMA_EV_READ) {
            FD_SET(fd, &read_fds_);
        } else {
            FD_CLR(fd, &read_fds_);
        }
        if (events & KUMA_EV_WRITE) {
            FD_SET(fd, &write_fds_);
        } else {
            FD_CLR(fd, &write_fds_);
        }
        if (events & KUMA_EV_ERROR) {
            FD_SET(fd, &except_fds_);
        }
        if (fd > max_fd_) {
            max_fd_ = fd;
        }
    } else {
        FD_CLR(fd, &read_fds_);
        FD_CLR(fd, &write_fds_);
        FD_CLR(fd, &except_fds_);
        if(max_fd_ == fd) {
            auto it = std::max_element(poll_fds_.begin(), poll_fds_.end(), [] (PollFD& pf1, PollFD& pf2){
                return pf1.fd < pf2.fd;
            });
            max_fd_ = it != poll_fds_.end()?(*it).fd:0;
        }
    }
}
예제 #3
0
파일: VPoll.cpp 프로젝트: Jamol/kuma
KMError VPoll::unregisterFd(SOCKET_FD fd)
{
    int max_fd = int(poll_items_.size() - 1);
    KUMA_INFOTRACE("VPoll::unregisterFd, fd="<<fd<<", max_fd="<<max_fd);
    if (fd < 0 || -1 == max_fd || fd > max_fd) {
        KUMA_WARNTRACE("VPoll::unregisterFd, failed, max_fd="<<max_fd);
        return KMError::INVALID_PARAM;
    }
    int idx = poll_items_[fd].idx;
    if(fd < max_fd) {
        poll_items_[fd].reset();
    } else if (fd == max_fd) {
        poll_items_.pop_back();
    }
    
    int last_idx = int(poll_fds_.size() - 1);
    if (idx > last_idx || -1 == idx) {
        return KMError::NOERR;
    }
    if (idx != last_idx) {
        std::iter_swap(poll_fds_.begin()+idx, poll_fds_.end()-1);
        poll_items_[poll_fds_[idx].fd].idx = idx;
    }
    poll_fds_.pop_back();
    return KMError::NOERR;
}
예제 #4
0
int SelectPoll::registerFd(SOCKET_FD fd, uint32_t events, IOCallback& cb)
{
    KUMA_INFOTRACE("SelectPoll::registerFd, fd="<<fd);
    resizePollItems(fd);
    if (INVALID_FD == poll_items_[fd].fd || -1 == poll_items_[fd].idx) {
        PollFD pfd;
        pfd.fd = fd;
        pfd.events = events;
        poll_fds_.push_back(pfd);
        poll_items_[fd].idx = int(poll_fds_.size() - 1);
    }
    poll_items_[fd].fd = fd;
    poll_items_[fd].cb = cb;
    updateFdSet(fd, events);
    return KUMA_ERROR_NOERR;
}
예제 #5
0
파일: VPoll.cpp 프로젝트: Jamol/kuma
KMError VPoll::registerFd(SOCKET_FD fd, KMEvent events, IOCallback cb)
{
    if (fd < 0) {
        return KMError::INVALID_PARAM;
    }
    resizePollItems(fd);
    int idx = -1;
    if (INVALID_FD == poll_items_[fd].fd || -1 == poll_items_[fd].idx) { // new
        pollfd pfd;
        pfd.fd = fd;
        pfd.events = get_events(events);
        poll_fds_.push_back(pfd);
        idx = int(poll_fds_.size() - 1);
        poll_items_[fd].idx = idx;
    }
    poll_items_[fd].fd = fd;
    poll_items_[fd].events = events;
    poll_items_[fd].cb = std::move(cb);
    KUMA_INFOTRACE("VPoll::registerFd, fd="<<fd<<", events="<<events<<", index="<<idx);
    
    return KMError::NOERR;
}
예제 #6
0
파일: VPoll.cpp 프로젝트: Jamol/kuma
KMError VPoll::wait(uint32_t wait_ms)
{
#ifdef KUMA_OS_WIN
    int num_revts = WSAPoll(&poll_fds_[0], poll_fds_.size(), wait_ms);
#else
    int num_revts = poll(&poll_fds_[0], (nfds_t)poll_fds_.size(), wait_ms);
#endif
    if (-1 == num_revts) {
        if(EINTR == errno) {
            errno = 0;
        } else {
            KUMA_ERRTRACE("VPoll::wait, err="<<getLastError());
        }
        return KMError::INVALID_STATE;
    }

    // copy poll fds since event handler may unregister fd
    PollFdVector poll_fds = poll_fds_;
    
    int idx = 0;
    int last_idx = int(poll_fds.size() - 1);
    while(num_revts > 0 && idx <= last_idx) {
        if(poll_fds[idx].revents) {
            --num_revts;
            if(poll_fds[idx].fd < poll_items_.size()) {
                auto &item = poll_items_[poll_fds[idx].fd];
                auto revents = get_kuma_events(poll_fds[idx].revents);
                revents &= item.events;
                if (revents && item.cb) {
                    item.cb(revents, nullptr, 0);
                }
            }
        }
        ++idx;
    }
    return KMError::NOERR;
}
예제 #7
0
int SelectPoll::updateFd(SOCKET_FD fd, uint32_t events)
{
    int max_fd = int(poll_items_.size() - 1);
    if (fd < 0 || -1 == max_fd || fd > max_fd) {
        KUMA_WARNTRACE("SelectPoll::updateFd, failed, fd="<<fd<<", max_fd="<<max_fd);
        return KUMA_ERROR_INVALID_PARAM;
    }
    if(poll_items_[fd].fd != fd) {
        KUMA_WARNTRACE("SelectPoll::updateFd, failed, fd="<<fd<<", item_fd="<<poll_items_[fd].fd);
        return KUMA_ERROR_INVALID_PARAM;
    }
    int idx = poll_items_[fd].idx;
    if (idx < 0 || idx >= poll_fds_.size()) {
        KUMA_WARNTRACE("SelectPoll::updateFd, failed, index="<<idx);
        return KUMA_ERROR_INVALID_STATE;
    }
    if(poll_fds_[idx].fd != fd) {
        KUMA_WARNTRACE("SelectPoll::updateFd, failed, fd="<<fd<<", pfds_fd="<<poll_fds_[idx].fd);
        return KUMA_ERROR_INVALID_PARAM;
    }
    poll_fds_[idx].events = events;
    updateFdSet(fd, events);
    return KUMA_ERROR_NOERR;
}
예제 #8
0
파일: VPoll.cpp 프로젝트: Jamol/kuma
KMError VPoll::updateFd(SOCKET_FD fd, KMEvent events)
{
    int max_fd = int(poll_items_.size() - 1);
    if (fd < 0 || -1 == max_fd || fd > max_fd) {
        KUMA_WARNTRACE("VPoll::updateFd, failed, fd="<<fd<<", max_fd="<<max_fd);
        return KMError::INVALID_PARAM;
    }
    if(poll_items_[fd].fd != fd) {
        KUMA_WARNTRACE("VPoll::updateFd, failed, fd="<<fd<<", item_fd="<<poll_items_[fd].fd);
        return KMError::INVALID_PARAM;
    }
    int idx = poll_items_[fd].idx;
    if (idx < 0 || idx >= poll_fds_.size()) {
        KUMA_WARNTRACE("VPoll::updateFd, failed, index="<<idx);
        return KMError::INVALID_STATE;
    }
    if(poll_fds_[idx].fd != fd) {
        KUMA_WARNTRACE("VPoll::updateFd, failed, fd="<<fd<<", pfds_fd="<<poll_fds_[idx].fd);
        return KMError::INVALID_PARAM;
    }
    poll_fds_[idx].events = get_events(events);
    poll_items_[fd].events = events;
    return KMError::NOERR;
}