From 9d9e0a8e895fb63e756c808eaa12bfa7f7c6fb4a Mon Sep 17 00:00:00 2001 From: chenkeyu Date: Thu, 6 Feb 2025 21:02:45 +0800 Subject: [PATCH] fix timer epoll_ctl operate on closed fd Issue: https://gitee.com/openharmony/commonlibrary_c_utils/issues/IBKHV4 Signed-off-by: chenkeyu --- base/src/event_demultiplexer.cpp | 29 ++++++++++++++++++++++++----- base/src/event_demultiplexer.h | 4 ++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/base/src/event_demultiplexer.cpp b/base/src/event_demultiplexer.cpp index 84ce34f..6d93eef 100644 --- a/base/src/event_demultiplexer.cpp +++ b/base/src/event_demultiplexer.cpp @@ -33,7 +33,8 @@ static const int EPOLL_ERROR_BADF = 9; static const int EPOLL_ERROR_EINVAL = 22; EventDemultiplexer::EventDemultiplexer() - : epollFd_(epoll_create1(EPOLL_CLOEXEC)), maxEvents_(EPOLL_MAX_EVENS_INIT), mutex_(), eventHandlers_() + : epollFd_(epoll_create1(EPOLL_CLOEXEC)), maxEvents_(EPOLL_MAX_EVENS_INIT), mutex_(), eventHandlers_(), + notFoundFds_(), epollCtlErrno_(0) { } @@ -71,6 +72,11 @@ uint32_t EventDemultiplexer::UpdateEventHandler(EventHandler* handler) auto itor = eventHandlers_.find(handler->GetHandle()); if (itor == eventHandlers_.end()) { eventHandlers_.insert(std::make_pair(handler->GetHandle(), handler->shared_from_this())); + // fd num reuse by a new timerfd, remove it from notFoundFds + auto notFoundFdItor = notFoundFds_.find(handler->GetHandle()); + if (notFoundFdItor != notFoundFds_.end()) { + notFoundFds_.erase(handler->GetHandle()); + } return Update(EPOLL_CTL_ADD, handler); } @@ -95,11 +101,25 @@ uint32_t EventDemultiplexer::Update(int operation, EventHandler* handler) if (epoll_ctl(epollFd_, operation, handler->GetHandle(), &event) != 0) { UTILS_LOGD("epoll_ctl %{public}d operation %{public}d on handle %{public}d failed", epollFd_, operation, handler->GetHandle()); + epollCtlErrno_ = errno; return TIMER_ERR_DEAL_FAILED; } return TIMER_ERR_OK; } +void EventDemultiplexer::HandleNotFoundFds(int targetFd) +{ + auto targetFdItor = notFoundFds_.find(targetFd); + if (targetFdItor != notFoundFds_.end()) { + notFoundFds_.insert(targetFd); + } else { + if (epoll_ctl(epollFd_, EPOLL_CTL_DEL, targetFd, nullptr) == -1) { + UTILS_LOGE("failed to DEL %{public}d from epoll, errno: %{public}d", targetFd, errno); + } + notFoundFds_.erase(targetFd); + } +} + int EventDemultiplexer::Polling(int timeout /* ms */) { std::vector epollEvents(maxEvents_); @@ -133,10 +153,9 @@ int EventDemultiplexer::Polling(int timeout /* ms */) taskQue.emplace_back(itor->second); eventQue.emplace_back(events); } else { - UTILS_LOGE("fd not found in eventHandlers_, fd=%{public}d, events=%{public}d", targetFd, events); - if (epoll_ctl(epollFd_, EPOLL_CTL_DEL, targetFd, nullptr) == -1) { - UTILS_LOGE("failed to DEL %{public}d from epoll, errno: %{public}d", targetFd, errno); - } + UTILS_LOGE("fd not found in eventHandlers_, fd=%{public}d, events=%{public}d, errno=%{public}d, setsize=%{public}zu", + targetFd, events, epollCtlErrno_, notFoundFds_.size()); + HandleNotFoundFds(targetFd); } } } diff --git a/base/src/event_demultiplexer.h b/base/src/event_demultiplexer.h index 75a3d7b..afc58f2 100644 --- a/base/src/event_demultiplexer.h +++ b/base/src/event_demultiplexer.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace OHOS { namespace Utils { @@ -42,6 +43,7 @@ public: private: uint32_t Update(int operation, EventHandler* handler); + void HandleNotFoundFds(int targetFd); static uint32_t Reactor2Epoll(uint32_t reactorEvent); static uint32_t Epoll2Reactor(uint32_t epollEvents); @@ -49,6 +51,8 @@ private: int maxEvents_; std::recursive_mutex mutex_; std::map> eventHandlers_; // guard by mutex_ + std::set notFoundFds_; + int epollCtlErrno_; }; } -- Gitee