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; }
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; }
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; }
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; }
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; }
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; }
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; }