1 /*
2 * Copyright (C) 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 #define MLOG_TAG "MediaLibraryPeriodWorker"
16
17 #include "medialibrary_period_worker.h"
18
19 #include "media_log.h"
20 #include "power_efficiency_manager.h"
21
22 using namespace std;
23
24 namespace OHOS {
25 namespace Media {
26
27 shared_ptr<MediaLibraryPeriodWorker> MediaLibraryPeriodWorker::periodWorkerInstance_{nullptr};
28 mutex MediaLibraryPeriodWorker::instanceMtx_;
29 mutex MediaLibraryPeriodWorker::mtx_;
30 atomic<bool> MediaLibraryPeriodWorker::stop_ = true;
31 std::map<int32_t, std::shared_ptr<MedialibraryPeriodTask>>MediaLibraryPeriodWorker::tasks_;
32 static constexpr int32_t NOTIFY_TIME = 100;
33 static constexpr int32_t UPDATE_ANALYSIS_TIME = 2000;
34 static constexpr int32_t WAIT_FOR_DETACH_TIME = 100;
35
GetInstance()36 shared_ptr<MediaLibraryPeriodWorker> MediaLibraryPeriodWorker::GetInstance()
37 {
38 if (periodWorkerInstance_ == nullptr) {
39 lock_guard<mutex> lockGuard(instanceMtx_);
40 if (periodWorkerInstance_ == nullptr) {
41 periodWorkerInstance_ = shared_ptr<MediaLibraryPeriodWorker>(new MediaLibraryPeriodWorker());
42 periodWorkerInstance_->Init();
43 }
44 }
45 return periodWorkerInstance_;
46 }
47
MediaLibraryPeriodWorker()48 MediaLibraryPeriodWorker::MediaLibraryPeriodWorker() {}
49
~MediaLibraryPeriodWorker()50 MediaLibraryPeriodWorker::~MediaLibraryPeriodWorker()
51 {
52 lock_guard<mutex> lockGuard(instanceMtx_);
53 stop_.store(true);
54 this_thread::sleep_for(chrono::milliseconds(WAIT_FOR_DETACH_TIME));
55 periodWorkerInstance_ = nullptr;
56 }
57
Init()58 void MediaLibraryPeriodWorker::Init()
59 {
60 auto notifyTask = make_shared<MedialibraryPeriodTask>(PeriodTaskType::COMMON_NOTIFY, NOTIFY_TIME, "notify worker");
61 auto cloudAnalysisAlbumTask = make_shared<MedialibraryPeriodTask>(PeriodTaskType::CLOUD_ANALYSIS_ALBUM,
62 UPDATE_ANALYSIS_TIME, "analysis worker");
63 tasks_[PeriodTaskType::COMMON_NOTIFY] = notifyTask;
64 tasks_[PeriodTaskType::CLOUD_ANALYSIS_ALBUM] = cloudAnalysisAlbumTask;
65 }
66
StartTask(PeriodTaskType periodTaskType,PeriodExecute periodExecute,PeriodTaskData * data)67 bool MediaLibraryPeriodWorker::StartTask(PeriodTaskType periodTaskType, PeriodExecute periodExecute,
68 PeriodTaskData *data)
69 {
70 lock_guard<mutex> lockGuard(mtx_);
71 auto task = tasks_.find(periodTaskType);
72 if (task == tasks_.end() || !task->second) {
73 return false;
74 }
75 task->second->isThreadRunning_.store(true);
76 task->second->isStop_.store(false);
77 task->second->executor_ = periodExecute;
78 task->second->data_ = data;
79 thread([this, periodTaskType]() { this->HandleTask(periodTaskType); }).detach();
80 return true;
81 }
82
83
StopThread(PeriodTaskType periodTaskType)84 void MediaLibraryPeriodWorker::StopThread(PeriodTaskType periodTaskType)
85 {
86 lock_guard<mutex> lockGuard(mtx_);
87 auto task = tasks_.find(periodTaskType);
88 if (task == tasks_.end() || !task->second) {
89 return;
90 }
91 task->second->isStop_.store(true);
92 }
93
IsThreadRunning(PeriodTaskType periodTaskType)94 bool MediaLibraryPeriodWorker::IsThreadRunning(PeriodTaskType periodTaskType)
95 {
96 lock_guard<mutex> lockGuard(mtx_);
97 auto task = tasks_.find(periodTaskType);
98 if (task == tasks_.end() || !task->second) {
99 return false;
100 }
101 return task->second->isThreadRunning_.load();
102 }
103
HandleTask(PeriodTaskType periodTaskType)104 void MediaLibraryPeriodWorker::HandleTask(PeriodTaskType periodTaskType)
105 {
106 std::shared_ptr<MedialibraryPeriodTask> task = nullptr;
107 {
108 lock_guard<mutex> lockGuard(mtx_);
109 auto iterator = tasks_.find(periodTaskType);
110 if (iterator == tasks_.end() || iterator->second == nullptr) {
111 return;
112 }
113 task = iterator->second;
114 }
115 string name = task->threadName_;
116 pthread_setname_np(pthread_self(), name.c_str());
117 MEDIA_INFO_LOG("start %{public}s", name.c_str());
118 stop_.store(false);
119 while (!stop_.load() && task->isThreadRunning_.load()) {
120 task->executor_(task->data_);
121 if (task->isStop_.load()) {
122 task->isThreadRunning_.store(false);
123 break;
124 }
125 this_thread::sleep_for(chrono::milliseconds(task->period_));
126 }
127 MEDIA_INFO_LOG("end %{public}s", name.c_str());
128 }
129 } // namespace Media
130 } // namespace OHOS