1b1b8bc3fSopenharmony_ci/* 2b1b8bc3fSopenharmony_ci * Copyright (C) 2022-2023 Huawei Device Co., Ltd. 3b1b8bc3fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1b8bc3fSopenharmony_ci * you may not use this file except in compliance with the License. 5b1b8bc3fSopenharmony_ci * You may obtain a copy of the License at 6b1b8bc3fSopenharmony_ci * 7b1b8bc3fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1b8bc3fSopenharmony_ci * 9b1b8bc3fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1b8bc3fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1b8bc3fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1b8bc3fSopenharmony_ci * See the License for the specific language governing permissions and 13b1b8bc3fSopenharmony_ci * limitations under the License. 14b1b8bc3fSopenharmony_ci */ 15b1b8bc3fSopenharmony_ci 16b1b8bc3fSopenharmony_ci#ifndef NET_MANAGER_TIMER_H 17b1b8bc3fSopenharmony_ci#define NET_MANAGER_TIMER_H 18b1b8bc3fSopenharmony_ci 19b1b8bc3fSopenharmony_ci#include <atomic> 20b1b8bc3fSopenharmony_ci#include <chrono> 21b1b8bc3fSopenharmony_ci#include <condition_variable> 22b1b8bc3fSopenharmony_ci#include <functional> 23b1b8bc3fSopenharmony_ci#include <memory> 24b1b8bc3fSopenharmony_ci#include <mutex> 25b1b8bc3fSopenharmony_ci#include <thread> 26b1b8bc3fSopenharmony_ci 27b1b8bc3fSopenharmony_ci#include "ffrt.h" 28b1b8bc3fSopenharmony_ci#include "ffrt_inner.h" 29b1b8bc3fSopenharmony_ci#include "net_mgr_log_wrapper.h" 30b1b8bc3fSopenharmony_ci 31b1b8bc3fSopenharmony_cinamespace OHOS { 32b1b8bc3fSopenharmony_cinamespace NetManagerStandard { 33b1b8bc3fSopenharmony_cistatic constexpr const int TIMER_MAX_INTERVAL_MS = 200; 34b1b8bc3fSopenharmony_ciclass FfrtTimer { 35b1b8bc3fSopenharmony_cipublic: 36b1b8bc3fSopenharmony_ci FfrtTimer() : stopStatus_(true), tryStopFlag_(false) {} 37b1b8bc3fSopenharmony_ci 38b1b8bc3fSopenharmony_ci FfrtTimer(const FfrtTimer &timer) 39b1b8bc3fSopenharmony_ci { 40b1b8bc3fSopenharmony_ci stopStatus_ = timer.stopStatus_.load(); 41b1b8bc3fSopenharmony_ci tryStopFlag_ = timer.tryStopFlag_.load(); 42b1b8bc3fSopenharmony_ci } 43b1b8bc3fSopenharmony_ci 44b1b8bc3fSopenharmony_ci ~FfrtTimer() 45b1b8bc3fSopenharmony_ci { 46b1b8bc3fSopenharmony_ci Stop(); 47b1b8bc3fSopenharmony_ci } 48b1b8bc3fSopenharmony_ci 49b1b8bc3fSopenharmony_ci void Start(int interval, std::function<void()> taskFun) 50b1b8bc3fSopenharmony_ci { 51b1b8bc3fSopenharmony_ci if (stopStatus_ == false) { 52b1b8bc3fSopenharmony_ci return; 53b1b8bc3fSopenharmony_ci } 54b1b8bc3fSopenharmony_ci NETMGR_LOG_D("start thread..."); 55b1b8bc3fSopenharmony_ci stopStatus_ = false; 56b1b8bc3fSopenharmony_ci std::function<void()> startTask = [this, interval, taskFun]() { 57b1b8bc3fSopenharmony_ci while (!tryStopFlag_) { 58b1b8bc3fSopenharmony_ci OneTiming(interval); 59b1b8bc3fSopenharmony_ci if (!tryStopFlag_) { 60b1b8bc3fSopenharmony_ci taskFun(); 61b1b8bc3fSopenharmony_ci } 62b1b8bc3fSopenharmony_ci } 63b1b8bc3fSopenharmony_ci 64b1b8bc3fSopenharmony_ci std::lock_guard<ffrt::mutex> locker(mutex_); 65b1b8bc3fSopenharmony_ci stopStatus_ = true; 66b1b8bc3fSopenharmony_ci timerCond_.notify_one(); 67b1b8bc3fSopenharmony_ci }; 68b1b8bc3fSopenharmony_ci ffrt::submit(std::move(startTask), {}, {}, ffrt::task_attr().name("timeStartTask")); 69b1b8bc3fSopenharmony_ci } 70b1b8bc3fSopenharmony_ci 71b1b8bc3fSopenharmony_ci void Stop() 72b1b8bc3fSopenharmony_ci { 73b1b8bc3fSopenharmony_ci if (stopStatus_ || tryStopFlag_) { 74b1b8bc3fSopenharmony_ci return; 75b1b8bc3fSopenharmony_ci } 76b1b8bc3fSopenharmony_ci NETMGR_LOG_D("stop thread..."); 77b1b8bc3fSopenharmony_ci tryStopFlag_ = true; 78b1b8bc3fSopenharmony_ci std::unique_lock<ffrt::mutex> locker(mutex_); 79b1b8bc3fSopenharmony_ci timerCond_.wait(locker, [this] { return stopStatus_ == true; }); 80b1b8bc3fSopenharmony_ci 81b1b8bc3fSopenharmony_ci if (stopStatus_ == true) { 82b1b8bc3fSopenharmony_ci tryStopFlag_ = false; 83b1b8bc3fSopenharmony_ci } 84b1b8bc3fSopenharmony_ci } 85b1b8bc3fSopenharmony_ci 86b1b8bc3fSopenharmony_ciprivate: 87b1b8bc3fSopenharmony_ci void OneTiming(int time) 88b1b8bc3fSopenharmony_ci { 89b1b8bc3fSopenharmony_ci int repeatCount = (time > TIMER_MAX_INTERVAL_MS) ? (time / TIMER_MAX_INTERVAL_MS) : 0; 90b1b8bc3fSopenharmony_ci int remainTime = (time > TIMER_MAX_INTERVAL_MS) ? (time % TIMER_MAX_INTERVAL_MS) : time; 91b1b8bc3fSopenharmony_ci while (!tryStopFlag_) { 92b1b8bc3fSopenharmony_ci if (repeatCount > 0) { 93b1b8bc3fSopenharmony_ci ffrt::this_task::sleep_for(std::chrono::milliseconds(TIMER_MAX_INTERVAL_MS)); 94b1b8bc3fSopenharmony_ci } else { 95b1b8bc3fSopenharmony_ci if (remainTime) { 96b1b8bc3fSopenharmony_ci ffrt::this_task::sleep_for(std::chrono::milliseconds(remainTime)); 97b1b8bc3fSopenharmony_ci } 98b1b8bc3fSopenharmony_ci break; 99b1b8bc3fSopenharmony_ci } 100b1b8bc3fSopenharmony_ci repeatCount--; 101b1b8bc3fSopenharmony_ci } 102b1b8bc3fSopenharmony_ci } 103b1b8bc3fSopenharmony_ci 104b1b8bc3fSopenharmony_ciprivate: 105b1b8bc3fSopenharmony_ci std::atomic<bool> stopStatus_; 106b1b8bc3fSopenharmony_ci std::atomic<bool> tryStopFlag_; 107b1b8bc3fSopenharmony_ci ffrt::mutex mutex_; 108b1b8bc3fSopenharmony_ci ffrt::condition_variable timerCond_; 109b1b8bc3fSopenharmony_ci}; 110b1b8bc3fSopenharmony_ci} // namespace NetManagerStandard 111b1b8bc3fSopenharmony_ci} // namespace OHOS 112b1b8bc3fSopenharmony_ci#endif // NET_MANAGER_TIMER_H 113