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([this] { this->TimerLoopFunc(); }); 37 pthread_setname_np(timerLoop.native_handle(), "OS_ATimer"); 38 } 39 ~AudioTimer()40 ~AudioTimer() 41 { 42 { 43 std::unique_lock<std::mutex> lck(timerMutex); 44 exitLoop = true; 45 isTimerStarted = !isTimerStarted; 46 timerCtrl.notify_one(); 47 } 48 if (timerLoop.joinable()) { 49 timerLoop.join(); 50 } 51 } 52 StartTimer(uint32_t duration)53 void StartTimer(uint32_t duration) 54 { 55 std::unique_lock<std::mutex> lck(timerMutex); 56 timeoutDuration = duration; 57 isTimerStarted = true; 58 timerCtrl.notify_one(); 59 } 60 StopTimer()61 void StopTimer() 62 { 63 std::unique_lock<std::mutex> lck(timerMutex); 64 isTimerStarted = false; 65 if (!isTimedOut) { 66 timerCtrl.notify_one(); 67 } 68 } 69 IsTimeOut()70 bool IsTimeOut() 71 { 72 return isTimedOut; 73 } 74 OnTimeOut()75 virtual void OnTimeOut() {}; 76 77 volatile std::atomic<bool> isTimedOut; 78 79 private: 80 std::thread timerLoop; 81 std::condition_variable timerCtrl; 82 volatile std::atomic<bool> isTimerStarted; 83 std::mutex timerMutex; 84 volatile bool exitLoop; 85 uint32_t timeoutDuration; 86 TimerLoopFunc()87 void TimerLoopFunc() 88 { 89 while (true) { 90 std::unique_lock<std::mutex> lck(timerMutex); 91 if (exitLoop) { 92 break; 93 } 94 if (isTimerStarted) { 95 if (!timerCtrl.wait_for(lck, std::chrono::seconds(timeoutDuration), 96 [this] { return CheckTimerStopped(); })) { 97 isTimedOut = true; 98 isTimerStarted = false; 99 OnTimeOut(); 100 } 101 } else { 102 timerCtrl.wait(lck, [this] { return CheckTimerStarted(); }); 103 isTimedOut = false; 104 } 105 } 106 } 107 CheckTimerStarted()108 bool CheckTimerStarted() 109 { 110 return this->isTimerStarted; 111 } 112 CheckTimerStopped()113 bool CheckTimerStopped() 114 { 115 return !this->isTimerStarted; 116 } 117 }; 118 } // namespace AudioStandard 119 } // namespace OHOS 120 #endif // AUDIO_TIMER_H 121