13f4cbf05Sopenharmony_ci/*
23f4cbf05Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License.
53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at
63f4cbf05Sopenharmony_ci *
73f4cbf05Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83f4cbf05Sopenharmony_ci *
93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and
133f4cbf05Sopenharmony_ci * limitations under the License.
143f4cbf05Sopenharmony_ci */
153f4cbf05Sopenharmony_ci#include "event_reactor.h"
163f4cbf05Sopenharmony_ci#include "event_handler.h"
173f4cbf05Sopenharmony_ci#include "event_demultiplexer.h"
183f4cbf05Sopenharmony_ci#include "timer_event_handler.h"
193f4cbf05Sopenharmony_ci#include "common_timer_errors.h"
203f4cbf05Sopenharmony_ci#include "utils_log.h"
213f4cbf05Sopenharmony_ci
223f4cbf05Sopenharmony_ci#include <cstdio>
233f4cbf05Sopenharmony_ci#include <unistd.h>
243f4cbf05Sopenharmony_ci#include <sys/syscall.h>
253f4cbf05Sopenharmony_ci
263f4cbf05Sopenharmony_cinamespace OHOS {
273f4cbf05Sopenharmony_cinamespace Utils {
283f4cbf05Sopenharmony_ci
293f4cbf05Sopenharmony_ciEventReactor::EventReactor()
303f4cbf05Sopenharmony_ci    :loopReady_(false), switch_(false), demultiplexer_(new EventDemultiplexer())
313f4cbf05Sopenharmony_ci{
323f4cbf05Sopenharmony_ci}
333f4cbf05Sopenharmony_ci
343f4cbf05Sopenharmony_ciEventReactor::~EventReactor()
353f4cbf05Sopenharmony_ci{
363f4cbf05Sopenharmony_ci}
373f4cbf05Sopenharmony_ci
383f4cbf05Sopenharmony_civoid EventReactor::UpdateEventHandler(EventHandler* handler)
393f4cbf05Sopenharmony_ci{
403f4cbf05Sopenharmony_ci    if ((handler != nullptr) && (handler->GetEventReactor() == this) && (demultiplexer_ != nullptr)) {
413f4cbf05Sopenharmony_ci        if (demultiplexer_->UpdateEventHandler(handler) != 0) {
423f4cbf05Sopenharmony_ci            UTILS_LOGE("updateEventHandler failed.");
433f4cbf05Sopenharmony_ci        }
443f4cbf05Sopenharmony_ci    }
453f4cbf05Sopenharmony_ci}
463f4cbf05Sopenharmony_ci
473f4cbf05Sopenharmony_ciuint32_t EventReactor::SetUp()
483f4cbf05Sopenharmony_ci{
493f4cbf05Sopenharmony_ci    if (demultiplexer_ == nullptr) {
503f4cbf05Sopenharmony_ci        return TIMER_ERR_INVALID_VALUE;
513f4cbf05Sopenharmony_ci    }
523f4cbf05Sopenharmony_ci
533f4cbf05Sopenharmony_ci    uint32_t ret = demultiplexer_->StartUp(); // return TIME_ERR_OK, if demultiplexer has been started.
543f4cbf05Sopenharmony_ci    if (ret != 0) {
553f4cbf05Sopenharmony_ci        UTILS_LOGE("demultiplexer startUp failed.");
563f4cbf05Sopenharmony_ci        return ret;
573f4cbf05Sopenharmony_ci    }
583f4cbf05Sopenharmony_ci
593f4cbf05Sopenharmony_ci    loopReady_ = true;
603f4cbf05Sopenharmony_ci    return TIMER_ERR_OK;
613f4cbf05Sopenharmony_ci}
623f4cbf05Sopenharmony_ci
633f4cbf05Sopenharmony_civoid EventReactor::CleanUp()
643f4cbf05Sopenharmony_ci{
653f4cbf05Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(mutex_);
663f4cbf05Sopenharmony_ci    for (auto &itor : timerEventHandlers_) {
673f4cbf05Sopenharmony_ci        itor->Uninitialize();
683f4cbf05Sopenharmony_ci    }
693f4cbf05Sopenharmony_ci}
703f4cbf05Sopenharmony_ci
713f4cbf05Sopenharmony_civoid EventReactor::RunLoop(int timeout) const
723f4cbf05Sopenharmony_ci{
733f4cbf05Sopenharmony_ci    if (demultiplexer_ == nullptr) {
743f4cbf05Sopenharmony_ci        UTILS_LOGE("demultiplexer_ is nullptr.");
753f4cbf05Sopenharmony_ci        return;
763f4cbf05Sopenharmony_ci    }
773f4cbf05Sopenharmony_ci
783f4cbf05Sopenharmony_ci    while (loopReady_ && switch_) {
793f4cbf05Sopenharmony_ci        if (demultiplexer_->Polling(timeout) == EPOLL_CRITICAL_ERROR) {
803f4cbf05Sopenharmony_ci            UTILS_LOGE("polling critical error occure: %{public}d", timeout);
813f4cbf05Sopenharmony_ci            break;
823f4cbf05Sopenharmony_ci        }
833f4cbf05Sopenharmony_ci    }
843f4cbf05Sopenharmony_ci
853f4cbf05Sopenharmony_ci    loopReady_ = false;
863f4cbf05Sopenharmony_ci}
873f4cbf05Sopenharmony_ci
883f4cbf05Sopenharmony_civoid EventReactor::SwitchOn()
893f4cbf05Sopenharmony_ci{
903f4cbf05Sopenharmony_ci    switch_ = true;
913f4cbf05Sopenharmony_ci}
923f4cbf05Sopenharmony_ci
933f4cbf05Sopenharmony_civoid EventReactor::SwitchOff()
943f4cbf05Sopenharmony_ci{
953f4cbf05Sopenharmony_ci    switch_ = false;
963f4cbf05Sopenharmony_ci}
973f4cbf05Sopenharmony_ci
983f4cbf05Sopenharmony_ciuint32_t EventReactor::ScheduleTimer(const TimerCallback& cb, uint32_t interval, int& timerFd, bool once)
993f4cbf05Sopenharmony_ci{
1003f4cbf05Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(mutex_);
1013f4cbf05Sopenharmony_ci    std::shared_ptr<TimerEventHandler> handler = std::make_shared<TimerEventHandler>(this, interval, once);
1023f4cbf05Sopenharmony_ci    handler->SetTimerCallback(cb);
1033f4cbf05Sopenharmony_ci    uint32_t ret = handler->Initialize();
1043f4cbf05Sopenharmony_ci    if (ret != TIMER_ERR_OK) {
1053f4cbf05Sopenharmony_ci        UTILS_LOGD("ScheduleTimer %{public}d initialize failed", interval);
1063f4cbf05Sopenharmony_ci        return ret;
1073f4cbf05Sopenharmony_ci    }
1083f4cbf05Sopenharmony_ci
1093f4cbf05Sopenharmony_ci    timerFd = handler->GetHandle();
1103f4cbf05Sopenharmony_ci    timerEventHandlers_.push_back(handler);
1113f4cbf05Sopenharmony_ci    return TIMER_ERR_OK;
1123f4cbf05Sopenharmony_ci}
1133f4cbf05Sopenharmony_ci
1143f4cbf05Sopenharmony_civoid EventReactor::CancelTimer(int timerFd)
1153f4cbf05Sopenharmony_ci{
1163f4cbf05Sopenharmony_ci    UTILS_LOGD("Cancel timer, timerFd: %{public}d.", timerFd);
1173f4cbf05Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(mutex_);
1183f4cbf05Sopenharmony_ci    auto itor = timerEventHandlers_.begin();
1193f4cbf05Sopenharmony_ci    for (; itor != timerEventHandlers_.end(); ++itor) {
1203f4cbf05Sopenharmony_ci        if ((*itor)->GetHandle() == timerFd) {
1213f4cbf05Sopenharmony_ci            (*itor)->Uninitialize();
1223f4cbf05Sopenharmony_ci            timerEventHandlers_.erase(itor);
1233f4cbf05Sopenharmony_ci            return;
1243f4cbf05Sopenharmony_ci        }
1253f4cbf05Sopenharmony_ci    }
1263f4cbf05Sopenharmony_ci}
1273f4cbf05Sopenharmony_ci
1283f4cbf05Sopenharmony_ci} // namespace Utils
1293f4cbf05Sopenharmony_ci} // namespace OHOS
130