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 #include "dm_constants.h"
17 #include "dm_log.h"
18 #include "dm_timer.h"
19
20 #include <thread>
21
22 namespace OHOS {
23 namespace DistributedHardware {
Timer(std::string name,int32_t time,TimerCallback callback)24 Timer::Timer(std::string name, int32_t time, TimerCallback callback)
25 : timerName_(name), expire_(steadyClock::now()), state_(true), timeOut_(time), callback_(callback) {};
26
DmTimer()27 DmTimer::DmTimer()
28 {
29 LOGI("DmTimer constructor");
30 }
31
~DmTimer()32 DmTimer::~DmTimer()
33 {
34 LOGI("DmTimer destructor");
35 DeleteAll();
36 if (timerState_) {
37 std::unique_lock<std::mutex> locker(timerStateMutex_);
38 stopTimerCondition_.wait(locker, [this] { return static_cast<bool>(!timerState_); });
39 }
40 }
41
StartTimer(std::string name,int32_t timeOut,TimerCallback callback)42 int32_t DmTimer::StartTimer(std::string name, int32_t timeOut, TimerCallback callback)
43 {
44 LOGI("DmTimer StartTimer %s", name.c_str());
45 if (name.empty() || timeOut <= MIN_TIME_OUT || timeOut > MAX_TIME_OUT || callback == nullptr) {
46 LOGI("DmTimer StartTimer input value invalid");
47 return DM_INPUT_PARA_EMPTY;
48 }
49
50 std::shared_ptr<Timer> timer = std::make_shared<Timer>(name, timeOut, callback);
51 {
52 std::lock_guard<std::mutex> locker(timerMutex_);
53 timerQueue_.push(timer);
54 timerMap_[name] = timer;
55 }
56
57 if (timerState_) {
58 LOGI("DmTimer is running");
59 return DM_OK;
60 }
61
62 TimerRunning();
63 {
64 std::unique_lock<std::mutex> locker(timerStateMutex_);
65 runTimerCondition_.wait(locker, [this] { return static_cast<bool>(timerState_); });
66 }
67 return DM_OK;
68 }
69
DeleteTimer(std::string timerName)70 int32_t DmTimer::DeleteTimer(std::string timerName)
71 {
72 if (timerName.empty()) {
73 LOGE("DmTimer DeleteTimer timer is null");
74 return DM_INPUT_PARA_EMPTY;
75 }
76
77 LOGI("DmTimer DeleteTimer name %s", timerName.c_str());
78 std::lock_guard<std::mutex> locker(timerMutex_);
79 for (auto iter : timerMap_) {
80 if (iter.second->timerName_ == timerName) {
81 iter.second->state_ = false;
82 return DM_OK;
83 }
84 }
85 LOGE("DmTimer DeleteTimer no have this timer");
86 return DM_INPUT_PARA_EMPTY;
87 }
88
DeleteAll()89 int32_t DmTimer::DeleteAll()
90 {
91 LOGI("DmTimer DeleteAll start");
92 std::lock_guard<std::mutex> locker(timerMutex_);
93 for (auto iter : timerMap_) {
94 iter.second->state_ = false;
95 }
96 return DM_OK;
97 }
98
TimerRunning()99 int32_t DmTimer::TimerRunning()
100 {
101 std::thread([this] () {
102 {
103 timerState_ = true;
104 std::unique_lock<std::mutex> locker(timerStateMutex_);
105 runTimerCondition_.notify_one();
106 }
107 while (!timerQueue_.empty() && timerState_) {
108 std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_TICK_MILLSECONDS));
109 while (std::chrono::duration_cast<timerDuration>(steadyClock::now()
110 - timerQueue_.top()->expire_).count() / MILLISECOND_TO_SECOND >= timerQueue_.top()->timeOut_
111 || !timerQueue_.top()->state_) {
112 std::string name = timerQueue_.top()->timerName_;
113 if (timerQueue_.top()->state_) {
114 timerQueue_.top()->callback_(name);
115 }
116
117 std::lock_guard<std::mutex> locker(timerMutex_);
118 timerQueue_.pop();
119 timerMap_.erase(name);
120 if (timerQueue_.empty()) {
121 break;
122 }
123 }
124 }
125 {
126 timerState_ = false;
127 std::unique_lock<std::mutex> locker(timerStateMutex_);
128 stopTimerCondition_.notify_one();
129 }
130 }).detach();
131 return DM_OK;
132 }
133 }
134 }