1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15#include "event_reactor.h" 16#include "event_handler.h" 17#include "event_demultiplexer.h" 18#include "timer_event_handler.h" 19#include "common_timer_errors.h" 20#include "utils_log.h" 21 22#include <cstdio> 23#include <unistd.h> 24#include <sys/syscall.h> 25 26namespace OHOS { 27namespace Utils { 28 29EventReactor::EventReactor() 30 :loopReady_(false), switch_(false), demultiplexer_(new EventDemultiplexer()) 31{ 32} 33 34EventReactor::~EventReactor() 35{ 36} 37 38void EventReactor::UpdateEventHandler(EventHandler* handler) 39{ 40 if ((handler != nullptr) && (handler->GetEventReactor() == this) && (demultiplexer_ != nullptr)) { 41 if (demultiplexer_->UpdateEventHandler(handler) != 0) { 42 UTILS_LOGE("updateEventHandler failed."); 43 } 44 } 45} 46 47uint32_t EventReactor::SetUp() 48{ 49 if (demultiplexer_ == nullptr) { 50 return TIMER_ERR_INVALID_VALUE; 51 } 52 53 uint32_t ret = demultiplexer_->StartUp(); // return TIME_ERR_OK, if demultiplexer has been started. 54 if (ret != 0) { 55 UTILS_LOGE("demultiplexer startUp failed."); 56 return ret; 57 } 58 59 loopReady_ = true; 60 return TIMER_ERR_OK; 61} 62 63void EventReactor::CleanUp() 64{ 65 std::lock_guard<std::recursive_mutex> lock(mutex_); 66 for (auto &itor : timerEventHandlers_) { 67 itor->Uninitialize(); 68 } 69} 70 71void EventReactor::RunLoop(int timeout) const 72{ 73 if (demultiplexer_ == nullptr) { 74 UTILS_LOGE("demultiplexer_ is nullptr."); 75 return; 76 } 77 78 while (loopReady_ && switch_) { 79 if (demultiplexer_->Polling(timeout) == EPOLL_CRITICAL_ERROR) { 80 UTILS_LOGE("polling critical error occure: %{public}d", timeout); 81 break; 82 } 83 } 84 85 loopReady_ = false; 86} 87 88void EventReactor::SwitchOn() 89{ 90 switch_ = true; 91} 92 93void EventReactor::SwitchOff() 94{ 95 switch_ = false; 96} 97 98uint32_t EventReactor::ScheduleTimer(const TimerCallback& cb, uint32_t interval, int& timerFd, bool once) 99{ 100 std::lock_guard<std::recursive_mutex> lock(mutex_); 101 std::shared_ptr<TimerEventHandler> handler = std::make_shared<TimerEventHandler>(this, interval, once); 102 handler->SetTimerCallback(cb); 103 uint32_t ret = handler->Initialize(); 104 if (ret != TIMER_ERR_OK) { 105 UTILS_LOGD("ScheduleTimer %{public}d initialize failed", interval); 106 return ret; 107 } 108 109 timerFd = handler->GetHandle(); 110 timerEventHandlers_.push_back(handler); 111 return TIMER_ERR_OK; 112} 113 114void EventReactor::CancelTimer(int timerFd) 115{ 116 UTILS_LOGD("Cancel timer, timerFd: %{public}d.", timerFd); 117 std::lock_guard<std::recursive_mutex> lock(mutex_); 118 auto itor = timerEventHandlers_.begin(); 119 for (; itor != timerEventHandlers_.end(); ++itor) { 120 if ((*itor)->GetHandle() == timerFd) { 121 (*itor)->Uninitialize(); 122 timerEventHandlers_.erase(itor); 123 return; 124 } 125 } 126} 127 128} // namespace Utils 129} // namespace OHOS 130