• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 
16 #ifndef NET_MANAGER_TIMER_H
17 #define NET_MANAGER_TIMER_H
18 
19 #include <atomic>
20 #include <chrono>
21 #include <condition_variable>
22 #include <functional>
23 #include <memory>
24 #include <mutex>
25 #include <thread>
26 
27 #include "net_mgr_log_wrapper.h"
28 
29 namespace OHOS {
30 namespace NetManagerStandard {
31 static constexpr const int TIMER_MAX_INTERVAL_MS = 200;
32 class Timer {
33 public:
Timer()34     Timer() : stopStatus_(true), tryStopFlag_(false) {}
35 
Timer(const Timer & timer)36     Timer(const Timer &timer)
37     {
38         stopStatus_ = timer.stopStatus_.load();
39         tryStopFlag_ = timer.tryStopFlag_.load();
40     }
41 
~Timer()42     ~Timer()
43     {
44         Stop();
45     }
46 
Start(int interval,std::function<void ()> taskFun)47     void Start(int interval, std::function<void()> taskFun)
48     {
49         if (stopStatus_ == false) {
50             return;
51         }
52         NETMGR_LOG_D("start thread...");
53         stopStatus_ = false;
54         std::thread([this, interval, taskFun]() {
55             while (!tryStopFlag_) {
56                 OneTiming(interval);
57                 if (!tryStopFlag_) {
58                     taskFun();
59                 }
60             }
61 
62             std::lock_guard<std::mutex> locker(mutex_);
63             stopStatus_ = true;
64             timerCond_.notify_one();
65         }).detach();
66     }
67 
Stop()68     void Stop()
69     {
70         if (stopStatus_ || tryStopFlag_) {
71             return;
72         }
73         NETMGR_LOG_D("stop thread...");
74         tryStopFlag_ = true;
75         std::unique_lock<std::mutex> locker(mutex_);
76         timerCond_.wait(locker, [this] { return stopStatus_ == true; });
77 
78         if (stopStatus_ == true) {
79             tryStopFlag_ = false;
80         }
81     }
82 
83 private:
OneTiming(int time)84     void OneTiming(int time)
85     {
86         int repeatCount = (time > TIMER_MAX_INTERVAL_MS) ? (time / TIMER_MAX_INTERVAL_MS) : 0;
87         int remainTime = (time > TIMER_MAX_INTERVAL_MS) ? (time % TIMER_MAX_INTERVAL_MS) : time;
88         while (!tryStopFlag_) {
89             if (repeatCount > 0) {
90                 std::this_thread::sleep_for(std::chrono::milliseconds(TIMER_MAX_INTERVAL_MS));
91             } else {
92                 if (remainTime) {
93                     std::this_thread::sleep_for(std::chrono::milliseconds(remainTime));
94                     remainTime = 0;
95                 }
96                 break;
97             }
98             repeatCount--;
99         }
100     }
101 
102 private:
103     std::atomic<bool> stopStatus_;
104     std::atomic<bool> tryStopFlag_;
105     std::mutex mutex_;
106     std::condition_variable timerCond_;
107 };
108 } // namespace NetManagerStandard
109 } // namespace OHOS
110 #endif // NET_MANAGER_TIMER_H
111