diff --git a/base/src/event_demultiplexer.cpp b/base/src/event_demultiplexer.cpp index 87df8a71f0527960f537ad45991a12f199ccca61..dc5299cf8164ca3a7222911337434f5513bdd6c9 100644 --- a/base/src/event_demultiplexer.cpp +++ b/base/src/event_demultiplexer.cpp @@ -70,7 +70,7 @@ uint32_t EventDemultiplexer::UpdateEventHandler(EventHandler* handler) std::lock_guard lock(mutex_); auto itor = eventHandlers_.find(handler->GetHandle()); if (itor == eventHandlers_.end()) { - eventHandlers_.insert(std::make_pair(handler->GetHandle(), handler)); + eventHandlers_.insert(std::make_pair(handler->GetHandle(), handler->shared_from_this())); return Update(EPOLL_CTL_ADD, handler); } @@ -79,7 +79,7 @@ uint32_t EventDemultiplexer::UpdateEventHandler(EventHandler* handler) return Update(EPOLL_CTL_DEL, handler); } - if (handler != itor->second) { + if (handler != itor->second.get()) { return TIMER_ERR_DEAL_FAILED; } return Update(EPOLL_CTL_MOD, handler); @@ -90,7 +90,7 @@ uint32_t EventDemultiplexer::Update(int operation, EventHandler* handler) struct epoll_event event; bzero(&event, sizeof(event)); event.events = Reactor2Epoll(handler->Events()); - event.data.ptr = reinterpret_cast(handler); + event.data.fd = handler->GetHandle(); if (epoll_ctl(epollFd_, operation, handler->GetHandle(), &event) != 0) { UTILS_LOGD("epoll_ctl %{public}d operation %{public}d on handle %{public}d failed", @@ -103,6 +103,9 @@ uint32_t EventDemultiplexer::Update(int operation, EventHandler* handler) void EventDemultiplexer::Polling(int timeout /* ms */) { std::vector epollEvents(maxEvents_); + std::vector> taskQue; + std::vector eventQue; + int nfds = epoll_wait(epollFd_, &epollEvents[0], static_cast(epollEvents.size()), timeout); if (nfds == 0) { return; @@ -112,15 +115,24 @@ void EventDemultiplexer::Polling(int timeout /* ms */) return; } - for (int idx = 0; idx < nfds; ++idx) { - uint32_t events = epollEvents[idx].events; - void* ptr = epollEvents[idx].data.ptr; - auto handler = reinterpret_cast(ptr); - if (handler != nullptr) { - handler->HandleEvents(Epoll2Reactor(events)); + { + std::lock_guard lock(mutex_); + for (int idx = 0; idx < nfds; ++idx) { + int targetFd = epollEvents[idx].data.fd; + uint32_t events = epollEvents[idx].events; + + auto itor = eventHandlers_.find(targetFd); + if (itor != eventHandlers_.end()) { + taskQue.emplace_back(itor->second); + eventQue.emplace_back(events); + } } } + for (int idx = 0; idx < taskQue.size() && idx < eventQue.size(); idx++) { + taskQue[idx]->HandleEvents(eventQue[idx]); + } + if (nfds == maxEvents_) { maxEvents_ *= HALF_OF_MAX_EVENT; } @@ -149,4 +161,4 @@ uint32_t EventDemultiplexer::Reactor2Epoll(uint32_t reactorEvent) } } -} +} \ No newline at end of file diff --git a/base/src/event_demultiplexer.h b/base/src/event_demultiplexer.h index 5c25e5663c090835009b9066f20ea6c67d439edc..13fe966d42c2c7c5f7716e88d888a0094424df18 100644 --- a/base/src/event_demultiplexer.h +++ b/base/src/event_demultiplexer.h @@ -17,6 +17,7 @@ #define UTILS_EVENT_DEMULTIPLEXER_H #include +#include #include #include @@ -47,7 +48,7 @@ private: int epollFd_; int maxEvents_; std::recursive_mutex mutex_; - std::map eventHandlers_; // guard by mutex_ + std::map> eventHandlers_; // guard by mutex_ }; } diff --git a/base/src/event_handler.h b/base/src/event_handler.h index af75cbea09bfb1a381843b1cf5a9c7e43465c8da..eeb550f39732a58ca3f9005cc8a2cca4e51c3a20 100644 --- a/base/src/event_handler.h +++ b/base/src/event_handler.h @@ -17,15 +17,17 @@ #define UTILS_EVENT_HANDLER_H #include -#include #include +#include +#include +#include namespace OHOS { namespace Utils { class EventReactor; -class EventHandler { +class EventHandler : public std::enable_shared_from_this { public: using Callback = std::function; diff --git a/base/src/timer.cpp b/base/src/timer.cpp index 4fc9a1d074152cbc73e4f1d00eda49808412c82c..fa6109e1a4c12d9f5cdcd9ed41fc49d150b2898d 100644 --- a/base/src/timer.cpp +++ b/base/src/timer.cpp @@ -53,6 +53,15 @@ void Timer::Shutdown(bool useJoin) std::lock_guard lock(mutex_); if (intervalToTimers_.empty()) { UTILS_LOGI("no event for epoll wait, use detach to shutdown"); + + int tmpTimerFd = INVALID_TIMER_FD; + uint32_t ret = reactor_->ScheduleTimer([](int unused) { + UTILS_LOGD("%{public}s:Pseudo-task invoked to get thread exited.", __func__); + }, 0, tmpTimerFd, true); // Add a task to avoid eternally blocking of epoll_wait + if (ret == TIMER_ERR_OK) { + UTILS_LOGD("%{public}s:Pseudo-task need to be scheduled.", __func__); + } + thread_.detach(); return; } diff --git a/base/src/timer_event_handler.h b/base/src/timer_event_handler.h index 3201480b565c24485bf547ee8318f73ee90e9618..1fd0bd69c231c84d671c9b78b57a5e76b16b99e2 100644 --- a/base/src/timer_event_handler.h +++ b/base/src/timer_event_handler.h @@ -55,7 +55,7 @@ private: uint32_t interval_; EventReactor* reactor_; - std::unique_ptr handler_; + std::shared_ptr handler_; TimerCallback callback_; };