• 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 #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 }