• 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 "medialibrary_async_worker.h"
17 #include "media_log.h"
18 
19 using namespace std;
20 
21 namespace OHOS {
22 namespace Media {
23 static const int32_t SUCCESS = 0;
24 static const int32_t WAIT_FOR_SECOND = 10;
25 static const int32_t BG_SLEEP_COUNT = 500;
26 static const int32_t FG_SLEEP_COUNT = 50;
27 static const int32_t REST_FOR_SECOND = 1;
28 static const int32_t REST_FOR_LONG_SECOND = 10;
29 shared_ptr<MediaLibraryAsyncWorker> MediaLibraryAsyncWorker::asyncWorkerInstance_{nullptr};
30 mutex MediaLibraryAsyncWorker::instanceLock_;
31 
GetInstance()32 shared_ptr<MediaLibraryAsyncWorker> MediaLibraryAsyncWorker::GetInstance()
33 {
34     if (asyncWorkerInstance_ == nullptr) {
35         lock_guard<mutex> lockGuard(instanceLock_);
36         asyncWorkerInstance_ = shared_ptr<MediaLibraryAsyncWorker>(new MediaLibraryAsyncWorker());
37     }
38     return asyncWorkerInstance_;
39 }
40 
MediaLibraryAsyncWorker()41 MediaLibraryAsyncWorker::MediaLibraryAsyncWorker() : isThreadExist_(false), isContinue_(false), doneTotal_(0)
42 {}
43 
~MediaLibraryAsyncWorker()44 MediaLibraryAsyncWorker::~MediaLibraryAsyncWorker()
45 {
46     isThreadExist_ = false;
47 }
48 
Init()49 void MediaLibraryAsyncWorker::Init()
50 {
51     isThreadExist_ = true;
52     isContinue_ = false;
53     doneTotal_ = 0;
54     thread(&MediaLibraryAsyncWorker::StartWorker, this).detach();
55 }
56 
Interrupt()57 void MediaLibraryAsyncWorker::Interrupt()
58 {
59     MEDIA_DEBUG_LOG("Interrupt");
60     ReleaseBgTask();
61 }
62 
Stop()63 void MediaLibraryAsyncWorker::Stop()
64 {
65     MEDIA_DEBUG_LOG("Stop");
66     ReleaseBgTask();
67     ReleaseFgTask();
68 }
69 
AddTask(const shared_ptr<MediaLibraryAsyncTask> & task,bool isFg)70 int32_t MediaLibraryAsyncWorker::AddTask(const shared_ptr<MediaLibraryAsyncTask> &task, bool isFg)
71 {
72     if (isFg) {
73         lock_guard<mutex> lockGuard(fgTaskLock_);
74         fgTaskQueue_.push(task);
75     } else {
76         lock_guard<mutex> lockGuard(bgTaskLock_);
77         bgTaskQueue_.push(task);
78     }
79 
80     if (!isThreadExist_.load() && (asyncWorkerInstance_ != nullptr)) {
81         asyncWorkerInstance_->Init();
82     }
83     std::unique_lock<std::mutex> lock(bgWorkLock_);
84     isContinue_ = true;
85     lock.unlock();
86     bgWorkCv_.notify_one();
87     return SUCCESS;
88 }
89 
GetFgTask()90 shared_ptr<MediaLibraryAsyncTask> MediaLibraryAsyncWorker::GetFgTask()
91 {
92     lock_guard<mutex> lockGuard(fgTaskLock_);
93     if (fgTaskQueue_.empty()) {
94         return nullptr;
95     }
96     shared_ptr<MediaLibraryAsyncTask> task = fgTaskQueue_.front();
97     fgTaskQueue_.pop();
98     return task;
99 }
100 
ReleaseFgTask()101 void MediaLibraryAsyncWorker::ReleaseFgTask()
102 {
103     lock_guard<mutex> lockGuard(fgTaskLock_);
104     std::queue<std::shared_ptr<MediaLibraryAsyncTask>> tmp;
105     fgTaskQueue_.swap(tmp);
106 }
107 
GetBgTask()108 shared_ptr<MediaLibraryAsyncTask> MediaLibraryAsyncWorker::GetBgTask()
109 {
110     lock_guard<mutex> lockGuard(bgTaskLock_);
111     if (bgTaskQueue_.empty()) {
112         return nullptr;
113     }
114     shared_ptr<MediaLibraryAsyncTask> task = bgTaskQueue_.front();
115     bgTaskQueue_.pop();
116     return task;
117 }
118 
ReleaseBgTask()119 void MediaLibraryAsyncWorker::ReleaseBgTask()
120 {
121     lock_guard<mutex> lockGuard(bgTaskLock_);
122     std::queue<std::shared_ptr<MediaLibraryAsyncTask>> tmp;
123     bgTaskQueue_.swap(tmp);
124 }
125 
IsFgQueueEmpty()126 bool MediaLibraryAsyncWorker::IsFgQueueEmpty()
127 {
128     lock_guard<mutex> lock_Guard(fgTaskLock_);
129     return fgTaskQueue_.empty();
130 }
131 
IsBgQueueEmpty()132 bool MediaLibraryAsyncWorker::IsBgQueueEmpty()
133 {
134     lock_guard<mutex> lock_Guard(bgTaskLock_);
135     return bgTaskQueue_.empty();
136 }
137 
WaitForTask()138 bool MediaLibraryAsyncWorker::WaitForTask()
139 {
140     std::unique_lock<std::mutex> lock(bgWorkLock_);
141     isContinue_ = false;
142     bool ret = bgWorkCv_.wait_for(lock, std::chrono::seconds(WAIT_FOR_SECOND),
143         [this]() { return isContinue_; });
144     return ret;
145 }
146 
SleepFgWork()147 void MediaLibraryAsyncWorker::SleepFgWork()
148 {
149     if ((doneTotal_.load() % FG_SLEEP_COUNT) == 0) {
150         this_thread::sleep_for(chrono::seconds(REST_FOR_SECOND));
151     }
152 }
153 
SleepBgWork()154 void MediaLibraryAsyncWorker::SleepBgWork()
155 {
156     this_thread::sleep_for(chrono::seconds(REST_FOR_SECOND));
157     if ((doneTotal_.load() % BG_SLEEP_COUNT) == 0) {
158         this_thread::sleep_for(chrono::seconds(REST_FOR_LONG_SECOND));
159     }
160 }
161 
StartWorker()162 void MediaLibraryAsyncWorker::StartWorker()
163 {
164     isThreadExist_ = true;
165     while (!IsFgQueueEmpty() || !IsBgQueueEmpty() || WaitForTask()) {
166         if (!IsFgQueueEmpty()) {
167             shared_ptr<MediaLibraryAsyncTask> fgTask = GetFgTask();
168             if (fgTask != nullptr) {
169                 fgTask->executor_(fgTask->data_);
170                 fgTask = nullptr;
171                 doneTotal_++;
172                 SleepFgWork();
173             }
174         } else if (!IsBgQueueEmpty()) {
175             shared_ptr<MediaLibraryAsyncTask> bgTask = GetBgTask();
176             if (bgTask != nullptr) {
177                 bgTask->executor_(bgTask->data_);
178                 bgTask = nullptr;
179                 doneTotal_++;
180                 SleepBgWork();
181             }
182         }
183     }
184     doneTotal_ = 0;
185     isThreadExist_ = false;
186 }
187 } // namespace Media
188 } // namespace OHOS
189