179a732c7Sopenharmony_ci/* 279a732c7Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 379a732c7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 479a732c7Sopenharmony_ci * you may not use this file except in compliance with the License. 579a732c7Sopenharmony_ci * You may obtain a copy of the License at 679a732c7Sopenharmony_ci * 779a732c7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 879a732c7Sopenharmony_ci * 979a732c7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1079a732c7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1179a732c7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1279a732c7Sopenharmony_ci * See the License for the specific language governing permissions and 1379a732c7Sopenharmony_ci * limitations under the License. 1479a732c7Sopenharmony_ci */ 1579a732c7Sopenharmony_ci 1679a732c7Sopenharmony_ci#include "dm_log.h" 1779a732c7Sopenharmony_ci#include "dm_timer.h" 1879a732c7Sopenharmony_ci 1979a732c7Sopenharmony_ci#include <pthread.h> 2079a732c7Sopenharmony_ci#include <thread> 2179a732c7Sopenharmony_ci 2279a732c7Sopenharmony_cinamespace OHOS { 2379a732c7Sopenharmony_cinamespace DistributedHardware { 2479a732c7Sopenharmony_ci 2579a732c7Sopenharmony_ciconstexpr const char* TIMER_RUNNING = "TimerRunning"; 2679a732c7Sopenharmony_ciconstexpr int32_t ERR_DM_INPUT_PARA_INVALID = -20006; 2779a732c7Sopenharmony_ciconstexpr int32_t DM_OK = 0; 2879a732c7Sopenharmony_ci 2979a732c7Sopenharmony_ciTimer::Timer(std::string name, int32_t time, TimerCallback callback) 3079a732c7Sopenharmony_ci : timerName_(name), expire_(steadyClock::now()), state_(true), timeOut_(time), callback_(callback) {}; 3179a732c7Sopenharmony_ci 3279a732c7Sopenharmony_ciDmTimer::DmTimer() 3379a732c7Sopenharmony_ci{ 3479a732c7Sopenharmony_ci} 3579a732c7Sopenharmony_ci 3679a732c7Sopenharmony_ciDmTimer::~DmTimer() 3779a732c7Sopenharmony_ci{ 3879a732c7Sopenharmony_ci LOGI("DmTimer destructor"); 3979a732c7Sopenharmony_ci DeleteAll(); 4079a732c7Sopenharmony_ci if (timerState_) { 4179a732c7Sopenharmony_ci std::unique_lock<std::mutex> locker(timerStateMutex_); 4279a732c7Sopenharmony_ci stopTimerCondition_.wait(locker, [this] { return static_cast<bool>(!timerState_); }); 4379a732c7Sopenharmony_ci } 4479a732c7Sopenharmony_ci} 4579a732c7Sopenharmony_ci 4679a732c7Sopenharmony_ciint32_t DmTimer::StartTimer(std::string name, int32_t timeOut, TimerCallback callback) 4779a732c7Sopenharmony_ci{ 4879a732c7Sopenharmony_ci LOGI("DmTimer StartTimer %{public}s", name.c_str()); 4979a732c7Sopenharmony_ci if (name.empty() || timeOut <= MIN_TIME_OUT || timeOut > MAX_TIME_OUT || callback == nullptr) { 5079a732c7Sopenharmony_ci LOGI("DmTimer StartTimer input value invalid"); 5179a732c7Sopenharmony_ci return ERR_DM_INPUT_PARA_INVALID; 5279a732c7Sopenharmony_ci } 5379a732c7Sopenharmony_ci 5479a732c7Sopenharmony_ci std::shared_ptr<Timer> timer = std::make_shared<Timer>(name, timeOut, callback); 5579a732c7Sopenharmony_ci { 5679a732c7Sopenharmony_ci std::lock_guard<std::mutex> locker(timerMutex_); 5779a732c7Sopenharmony_ci timerQueue_.push(timer); 5879a732c7Sopenharmony_ci timerVec_.emplace_back(timer); 5979a732c7Sopenharmony_ci } 6079a732c7Sopenharmony_ci 6179a732c7Sopenharmony_ci if (timerState_) { 6279a732c7Sopenharmony_ci LOGI("DmTimer is running"); 6379a732c7Sopenharmony_ci return DM_OK; 6479a732c7Sopenharmony_ci } 6579a732c7Sopenharmony_ci 6679a732c7Sopenharmony_ci TimerRunning(); 6779a732c7Sopenharmony_ci { 6879a732c7Sopenharmony_ci std::unique_lock<std::mutex> locker(timerStateMutex_); 6979a732c7Sopenharmony_ci runTimerCondition_.wait(locker, [this] { return static_cast<bool>(timerState_); }); 7079a732c7Sopenharmony_ci } 7179a732c7Sopenharmony_ci return DM_OK; 7279a732c7Sopenharmony_ci} 7379a732c7Sopenharmony_ci 7479a732c7Sopenharmony_ciint32_t DmTimer::DeleteTimer(std::string timerName) 7579a732c7Sopenharmony_ci{ 7679a732c7Sopenharmony_ci if (timerName.empty()) { 7779a732c7Sopenharmony_ci LOGE("DmTimer DeleteTimer timer is null"); 7879a732c7Sopenharmony_ci return ERR_DM_INPUT_PARA_INVALID; 7979a732c7Sopenharmony_ci } 8079a732c7Sopenharmony_ci 8179a732c7Sopenharmony_ci LOGI("DmTimer DeleteTimer name %{public}s", timerName.c_str()); 8279a732c7Sopenharmony_ci std::lock_guard<std::mutex> locker(timerMutex_); 8379a732c7Sopenharmony_ci for (auto iter : timerVec_) { 8479a732c7Sopenharmony_ci if (iter != nullptr && iter->timerName_ == timerName) { 8579a732c7Sopenharmony_ci iter->state_ = false; 8679a732c7Sopenharmony_ci } 8779a732c7Sopenharmony_ci } 8879a732c7Sopenharmony_ci return DM_OK; 8979a732c7Sopenharmony_ci} 9079a732c7Sopenharmony_ci 9179a732c7Sopenharmony_ciint32_t DmTimer::DeleteAll() 9279a732c7Sopenharmony_ci{ 9379a732c7Sopenharmony_ci LOGI("DmTimer DeleteAll start"); 9479a732c7Sopenharmony_ci std::lock_guard<std::mutex> locker(timerMutex_); 9579a732c7Sopenharmony_ci for (auto iter : timerVec_) { 9679a732c7Sopenharmony_ci LOGI("DmTimer DeleteAll timer.name = %{public}s ", iter->timerName_.c_str()); 9779a732c7Sopenharmony_ci iter->state_ = false; 9879a732c7Sopenharmony_ci } 9979a732c7Sopenharmony_ci return DM_OK; 10079a732c7Sopenharmony_ci} 10179a732c7Sopenharmony_ci 10279a732c7Sopenharmony_ciint32_t DmTimer::TimerRunning() 10379a732c7Sopenharmony_ci{ 10479a732c7Sopenharmony_ci int32_t ret = pthread_setname_np(pthread_self(), TIMER_RUNNING); 10579a732c7Sopenharmony_ci if (ret != DM_OK) { 10679a732c7Sopenharmony_ci LOGE("TimerRunning setname failed."); 10779a732c7Sopenharmony_ci } 10879a732c7Sopenharmony_ci std::thread([this] () { 10979a732c7Sopenharmony_ci { 11079a732c7Sopenharmony_ci timerState_ = true; 11179a732c7Sopenharmony_ci std::unique_lock<std::mutex> locker(timerStateMutex_); 11279a732c7Sopenharmony_ci runTimerCondition_.notify_one(); 11379a732c7Sopenharmony_ci } 11479a732c7Sopenharmony_ci while (!timerQueue_.empty() && timerState_) { 11579a732c7Sopenharmony_ci std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_TICK_MILLSECONDS)); 11679a732c7Sopenharmony_ci timerMutex_.lock(); 11779a732c7Sopenharmony_ci while (!timerQueue_.empty() && (std::chrono::duration_cast<timerDuration>(steadyClock::now() - 11879a732c7Sopenharmony_ci timerQueue_.top()->expire_).count() / MILLISECOND_TO_SECOND >= timerQueue_.top()->timeOut_ || 11979a732c7Sopenharmony_ci !timerQueue_.top()->state_)) { 12079a732c7Sopenharmony_ci std::string name = timerQueue_.top()->timerName_; 12179a732c7Sopenharmony_ci LOGI("DmTimer TimerRunning timer.name = %{public}s", name.c_str()); 12279a732c7Sopenharmony_ci TimerCallback callBack = nullptr; 12379a732c7Sopenharmony_ci if (timerQueue_.top()->state_) { 12479a732c7Sopenharmony_ci callBack = timerQueue_.top()->callback_; 12579a732c7Sopenharmony_ci } 12679a732c7Sopenharmony_ci timerQueue_.pop(); 12779a732c7Sopenharmony_ci DeleteVector(name); 12879a732c7Sopenharmony_ci timerMutex_.unlock(); 12979a732c7Sopenharmony_ci if (callBack != nullptr) { 13079a732c7Sopenharmony_ci callBack(name); 13179a732c7Sopenharmony_ci } 13279a732c7Sopenharmony_ci timerMutex_.lock(); 13379a732c7Sopenharmony_ci if (timerQueue_.empty()) { 13479a732c7Sopenharmony_ci break; 13579a732c7Sopenharmony_ci } 13679a732c7Sopenharmony_ci } 13779a732c7Sopenharmony_ci timerMutex_.unlock(); 13879a732c7Sopenharmony_ci } 13979a732c7Sopenharmony_ci { 14079a732c7Sopenharmony_ci timerState_ = false; 14179a732c7Sopenharmony_ci std::unique_lock<std::mutex> locker(timerStateMutex_); 14279a732c7Sopenharmony_ci stopTimerCondition_.notify_one(); 14379a732c7Sopenharmony_ci } 14479a732c7Sopenharmony_ci }).detach(); 14579a732c7Sopenharmony_ci return DM_OK; 14679a732c7Sopenharmony_ci} 14779a732c7Sopenharmony_ci 14879a732c7Sopenharmony_civoid DmTimer::DeleteVector(std::string name) 14979a732c7Sopenharmony_ci{ 15079a732c7Sopenharmony_ci for (auto iter = timerVec_.begin(); iter != timerVec_.end(); ++iter) { 15179a732c7Sopenharmony_ci if ((*iter)->timerName_ == name) { 15279a732c7Sopenharmony_ci timerVec_.erase(iter); 15379a732c7Sopenharmony_ci break; 15479a732c7Sopenharmony_ci } 15579a732c7Sopenharmony_ci } 15679a732c7Sopenharmony_ci} 15779a732c7Sopenharmony_ci} 15879a732c7Sopenharmony_ci}