• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 AUDIO_TIMER_H
17 #define AUDIO_TIMER_H
18 
19 #include <atomic>
20 #include <condition_variable>
21 #include <mutex>
22 #include <thread>
23 #include <functional>
24 
25 namespace OHOS {
26 namespace AudioStandard {
27 const uint32_t WAIT_TIMEOUT_IN_SECS = 5;
28 
29 class AudioTimer {
30 public:
AudioTimer()31     AudioTimer()
32         : AudioTimer(nullptr)
33     {
34     }
35 
AudioTimer(std::function<void ()> func)36     AudioTimer(std::function<void()> func)
37     {
38         timeoutDuration = WAIT_TIMEOUT_IN_SECS;
39         isTimerStarted = false;
40         isTimedOut     = false;
41         exitLoop       =  false;
42         timeOutCallBack_ = func;
43         timerLoop = std::thread([this] { this->TimerLoopFunc(); });
44         pthread_setname_np(timerLoop.native_handle(), "OS_ATimer");
45     }
46 
~AudioTimer()47     virtual ~AudioTimer()
48     {
49         {
50             std::unique_lock<std::mutex> lck(timerMutex);
51             exitLoop = true;
52             isTimerStarted = !isTimerStarted;
53             timerCtrl.notify_one();
54         }
55         if (timerLoop.joinable()) {
56             timerLoop.join();
57         }
58     }
59 
StartTimer(uint32_t duration)60     void StartTimer(uint32_t duration)
61     {
62         std::unique_lock<std::mutex> lck(timerMutex);
63         timeoutDuration = duration;
64         isTimerStarted = true;
65         timerCtrl.notify_one();
66     }
67 
StopTimer()68     void StopTimer()
69     {
70         std::unique_lock<std::mutex> lck(timerMutex);
71         isTimerStarted = false;
72         if (!isTimedOut) {
73             timerCtrl.notify_one();
74         }
75     }
76 
IsTimeOut()77     bool IsTimeOut()
78     {
79         return isTimedOut;
80     }
81 
OnTimeOut()82     virtual void OnTimeOut() {};
83 
84     volatile std::atomic<bool> isTimedOut;
85 
86 private:
87     std::thread timerLoop;
88     std::condition_variable timerCtrl;
89     volatile std::atomic<bool> isTimerStarted;
90     std::mutex timerMutex;
91     volatile bool exitLoop;
92     uint32_t timeoutDuration;
93     std::function<void()> timeOutCallBack_ = nullptr;
94 
TimerLoopFunc()95     void TimerLoopFunc()
96     {
97         while (true) {
98             bool isCallBack = false;
99             {
100                 std::unique_lock<std::mutex> lck(timerMutex);
101                 if (exitLoop) {
102                     break;
103                 }
104                 if (isTimerStarted) {
105                     if (!timerCtrl.wait_for(lck, std::chrono::seconds(timeoutDuration),
106                         [this] { return CheckTimerStopped() || exitLoop; })) {
107                         isTimedOut = true;
108                         isCallBack = !exitLoop;
109                         isTimerStarted = false;
110                         OnTimeOut();
111                     }
112                 } else {
113                     timerCtrl.wait(lck, [this] { return CheckTimerStarted() || exitLoop; });
114                     isTimedOut = false;
115                 }
116             }
117             if (isCallBack && timeOutCallBack_ != nullptr) {
118                 timeOutCallBack_();
119             }
120         }
121     }
122 
CheckTimerStarted()123     bool CheckTimerStarted()
124     {
125         return this->isTimerStarted;
126     }
127 
CheckTimerStopped()128     bool CheckTimerStopped()
129     {
130         return !this->isTimerStarted;
131     }
132 };
133 } // namespace AudioStandard
134 } // namespace OHOS
135 #endif // AUDIO_TIMER_H
136