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 24 namespace OHOS { 25 namespace AudioStandard { 26 const int WAIT_TIMEOUT_IN_SECS = 5; 27 28 class AudioTimer { 29 public: AudioTimer()30 AudioTimer() 31 { 32 timeoutDuration = WAIT_TIMEOUT_IN_SECS; 33 isTimerStarted = false; 34 isTimedOut = false; 35 exitLoop = false; 36 timerLoop = std::thread(&AudioTimer::TimerLoopFunc, this); 37 } 38 ~AudioTimer()39 ~AudioTimer() 40 { 41 exitLoop = true; 42 isTimerStarted = false; 43 timerCtrl.notify_one(); 44 isTimerStarted = true; 45 timerCtrl.notify_one(); 46 timerLoop.join(); 47 } 48 StartTimer(uint32_t duration)49 void StartTimer(uint32_t duration) 50 { 51 timeoutDuration = duration; 52 isTimerStarted = true; 53 timerCtrl.notify_one(); 54 } 55 StopTimer()56 void StopTimer() 57 { 58 isTimerStarted = false; 59 if (!isTimedOut) { 60 timerCtrl.notify_one(); 61 } 62 } 63 IsTimeOut()64 bool IsTimeOut() 65 { 66 return isTimedOut; 67 } 68 69 virtual void OnTimeOut() = 0; 70 71 volatile std::atomic<bool> isTimedOut; 72 73 private: 74 std::thread timerLoop; 75 std::condition_variable timerCtrl; 76 volatile std::atomic<bool> isTimerStarted; 77 std::mutex timerMutex; 78 volatile bool exitLoop; 79 uint32_t timeoutDuration; 80 TimerLoopFunc()81 void TimerLoopFunc() 82 { 83 while (true) { 84 std::unique_lock<std::mutex> lck(timerMutex); 85 timerCtrl.wait(lck, [this] { return CheckTimerStarted(); }); 86 isTimedOut = false; 87 if (exitLoop) break; 88 if (!timerCtrl.wait_for(lck, std::chrono::seconds(timeoutDuration), 89 [this] { return CheckTimerStopped(); })) { 90 isTimedOut = true; 91 isTimerStarted = false; 92 OnTimeOut(); 93 } 94 } 95 } 96 CheckTimerStarted()97 bool CheckTimerStarted() 98 { 99 return this->isTimerStarted; 100 } 101 CheckTimerStopped()102 bool CheckTimerStopped() 103 { 104 return !this->isTimerStarted; 105 } 106 }; 107 } // namespace AudioStandard 108 } // namespace OHOS 109 #endif // AUDIO_TIMER_H 110