1 /*
2  * Copyright (c) 2022-2024 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 "dh_timer.h"
17 
18 #include <pthread.h>
19 
20 #include "anonymous_string.h"
21 #include "constants.h"
22 #include "distributed_hardware_errno.h"
23 #include "distributed_hardware_log.h"
24 
25 namespace OHOS {
26 namespace DistributedHardware {
27 #undef DH_LOG_TAG
28 #define DH_LOG_TAG "DHTimer"
29 
DHTimer(std::string timerId,int32_t delayTimeMs)30 DHTimer::DHTimer(std::string timerId, int32_t delayTimeMs) : timerId_(timerId), delayTimeMs_(delayTimeMs)
31 {
32     DHLOGI("DHTimer ctor!");
33 }
34 
~DHTimer()35 DHTimer::~DHTimer()
36 {
37     DHLOGI("DHTimer dtor!");
38     ReleaseTimer();
39 }
40 
InitTimer()41 void DHTimer::InitTimer()
42 {
43     DHLOGI("start");
44     std::unique_lock<std::mutex> lock(timerMutex_);
45     if (eventHandler_ == nullptr) {
46         eventHandlerThread_ = std::thread([this]() { this->StartEventRunner(); });
47         timerCond_.wait(lock, [this] { return eventHandler_ != nullptr; });
48     }
49     DHLOGI("end");
50 }
51 
ReleaseTimer()52 void DHTimer::ReleaseTimer()
53 {
54     DHLOGI("start");
55     std::lock_guard<std::mutex> lock(timerMutex_);
56     if (eventHandler_ != nullptr) {
57         eventHandler_->RemoveTask(timerId_);
58         if (eventHandler_->GetEventRunner() != nullptr) {
59             eventHandler_->GetEventRunner()->Stop();
60         }
61     }
62     if (eventHandlerThread_.joinable()) {
63         eventHandlerThread_.join();
64     }
65     eventHandler_ = nullptr;
66     DHLOGI("end");
67 }
68 
StartEventRunner()69 void DHTimer::StartEventRunner()
70 {
71     DHLOGI("start");
72     int32_t ret = pthread_setname_np(pthread_self(), EVENT_RUN);
73     if (ret != DH_FWK_SUCCESS) {
74         DHLOGE("StartEventRunner setname failed.");
75     }
76     auto busRunner = AppExecFwk::EventRunner::Create(false);
77     if (busRunner == nullptr) {
78         DHLOGE("busRunner is nullptr!");
79         return;
80     }
81     {
82         std::lock_guard<std::mutex> lock(timerMutex_);
83         eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(busRunner);
84     }
85     timerCond_.notify_all();
86     busRunner->Run();
87     DHLOGI("end");
88 }
89 
StartTimer()90 void DHTimer::StartTimer()
91 {
92     DHLOGI("start");
93     InitTimer();
94     std::lock_guard<std::mutex> lock(timerMutex_);
95     if (eventHandler_ == nullptr) {
96         DHLOGE("eventHandler is nullptr");
97         return;
98     }
99     auto executeFunc = [this] { Execute(); };
100     eventHandler_->PostTask(executeFunc, timerId_, delayTimeMs_);
101 }
102 
StopTimer()103 void DHTimer::StopTimer()
104 {
105     DHLOGI("start");
106     ReleaseTimer();
107     HandleStopTimer();
108     DHLOGI("end");
109 }
110 
Execute()111 void DHTimer::Execute()
112 {
113     DHLOGI("start");
114     std::lock_guard<std::mutex> lock(timerMutex_);
115     if (eventHandler_ == nullptr) {
116         DHLOGE("eventHandler is nullptr!");
117         return;
118     }
119     ExecuteInner();
120     auto executeInnerFunc = [this] { Execute(); };
121     eventHandler_->PostTask(executeInnerFunc, timerId_, delayTimeMs_);
122 }
123 } // namespace DistributedHardware
124 } // namespace OHOS
125