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 namespace OHOS {
23 namespace Utils {
24
EventReactor()25 EventReactor::EventReactor()
26 :loopReady_(false), switch_(false), demultiplexer_(new EventDemultiplexer())
27 {
28 }
29
~EventReactor()30 EventReactor::~EventReactor()
31 {
32 }
33
UpdateEventHandler(EventHandler * handler)34 void EventReactor::UpdateEventHandler(EventHandler* handler)
35 {
36 if ((handler != nullptr) && (handler->GetEventReactor() == this) && (demultiplexer_ != nullptr)) {
37 if (demultiplexer_->UpdateEventHandler(handler) != 0) {
38 UTILS_LOGE("updateEventHandler failed.");
39 }
40 }
41 }
42
SetUp()43 uint32_t EventReactor::SetUp()
44 {
45 if (demultiplexer_ == nullptr) {
46 return TIMER_ERR_INVALID_VALUE;
47 }
48
49 uint32_t ret = demultiplexer_->StartUp(); // return TIME_ERR_OK, if demultiplexer has been started.
50 if (ret != 0) {
51 UTILS_LOGE("demultiplexer startUp failed.");
52 return ret;
53 }
54
55 loopReady_ = true;
56 return TIMER_ERR_OK;
57 }
58
CleanUp()59 void EventReactor::CleanUp()
60 {
61 std::lock_guard<std::recursive_mutex> lock(mutex_);
62 for (auto &itor : timerEventHandlers_) {
63 itor->Uninitialize();
64 }
65 }
66
RunLoop(int timeout) const67 void EventReactor::RunLoop(int timeout) const
68 {
69 if (demultiplexer_ == nullptr) {
70 UTILS_LOGE("demultiplexer_ is nullptr.");
71 return;
72 }
73
74 std::vector<epoll_event> epollEvents(demultiplexer_->GetMaxEvents());
75 while (loopReady_ && switch_) {
76 if (demultiplexer_->Polling(timeout, epollEvents) == EPOLL_CRITICAL_ERROR) {
77 UTILS_LOGD("polling critical error occure: %{public}d", timeout);
78 break;
79 }
80 }
81
82 loopReady_ = false;
83 }
84
SwitchOn()85 void EventReactor::SwitchOn()
86 {
87 switch_ = true;
88 }
89
SwitchOff()90 void EventReactor::SwitchOff()
91 {
92 switch_ = false;
93 }
94
ScheduleTimer(const TimerCallback & cb,uint32_t interval,int & timerFd,bool once)95 uint32_t EventReactor::ScheduleTimer(const TimerCallback& cb, uint32_t interval, int& timerFd, bool once)
96 {
97 std::lock_guard<std::recursive_mutex> lock(mutex_);
98 std::shared_ptr<TimerEventHandler> handler = std::make_shared<TimerEventHandler>(this, interval, once);
99 handler->SetTimerCallback(cb);
100 uint32_t ret = handler->Initialize();
101 if (ret != TIMER_ERR_OK) {
102 UTILS_LOGD("ScheduleTimer %{public}d initialize failed", interval);
103 return ret;
104 }
105
106 timerFd = handler->GetHandle();
107 timerEventHandlers_.push_back(handler);
108 return TIMER_ERR_OK;
109 }
110
CancelTimer(int timerFd)111 void EventReactor::CancelTimer(int timerFd)
112 {
113 UTILS_LOGD("Cancel timer, timerFd: %{public}d.", timerFd);
114 std::lock_guard<std::recursive_mutex> lock(mutex_);
115 auto itor = timerEventHandlers_.begin();
116 for (; itor != timerEventHandlers_.end(); ++itor) {
117 if ((*itor)->GetHandle() == timerFd) {
118 (*itor)->Uninitialize();
119 timerEventHandlers_.erase(itor);
120 return;
121 }
122 }
123 }
124
125 } // namespace Utils
126 } // namespace OHOS
127