• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2021 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 HST_LOG_TAG "Task"
16 
17 #include "foundation/osal/thread/task.h"
18 #include "foundation/cpp_ext/memory_ext.h"
19 #include "foundation/log.h"
20 
21 namespace OHOS {
22 namespace Media {
23 namespace OSAL {
Task(std::string name,ThreadPriority priority)24 Task::Task(std::string name, ThreadPriority priority)
25     : name_(std::move(name)), priority_(priority), runningState_(RunningState::STOPPED)
26 {
27     MEDIA_LOG_D("task " PUBLIC_LOG_S " ctor called", name_.c_str());
28     loop_ = CppExt::make_unique<OSAL::Thread>(priority);
29     loop_->SetName(name_);
30 }
31 
Task(std::string name,std::function<void ()> handler,ThreadPriority priority)32 Task::Task(std::string name, std::function<void()> handler, ThreadPriority priority)
33     : Task(std::move(name), priority)
34 {
35     MEDIA_LOG_D("task " PUBLIC_LOG_S " ctor called", name_.c_str());
36     handler_ = std::move(handler);
37 }
38 
~Task()39 Task::~Task()
40 {
41     MEDIA_LOG_I("task " PUBLIC_LOG_S " dtor called", name_.c_str());
42     runningState_ = RunningState::STOPPED;
43     syncCond_.NotifyAll();
44 }
45 
Start()46 void Task::Start()
47 {
48 #ifndef START_FAKE_TASK
49     MEDIA_LOG_I("task " PUBLIC_LOG_S " start called", name_.c_str());
50     OSAL::ScopedLock lock(stateMutex_);
51     runningState_ = RunningState::STARTED;
52     if (!loop_) { // thread not exist
53         loop_ = CppExt::make_unique<OSAL::Thread>(priority_);
54     }
55     if (!loop_->HasThread() && !loop_->CreateThread([this] { Run(); })) {
56         MEDIA_LOG_E("task " PUBLIC_LOG_S " create failed", name_.c_str());
57     } else {
58         syncCond_.NotifyAll();
59     }
60 #endif
61 }
62 
Stop()63 void Task::Stop()
64 {
65     MEDIA_LOG_W("task " PUBLIC_LOG_S " stop entered, current state: " PUBLIC_LOG_D32,
66                 name_.c_str(), runningState_.load());
67     OSAL::ScopedLock lock(stateMutex_);
68     if (runningState_.load() != RunningState::STOPPED) {
69         runningState_ = RunningState::STOPPING;
70         syncCond_.NotifyAll();
71         syncCond_.Wait(lock, [this] { return runningState_.load() == RunningState::STOPPED; });
72         if (loop_ && loop_->HasThread()) {
73             loop_ = nullptr;
74         }
75     }
76     MEDIA_LOG_W("task " PUBLIC_LOG_S " stop exited", name_.c_str());
77 }
78 
StopAsync()79 void Task::StopAsync()
80 {
81     MEDIA_LOG_D("task " PUBLIC_LOG_S " StopAsync called", name_.c_str());
82     OSAL::ScopedLock lock(stateMutex_);
83     if (runningState_.load() != RunningState::STOPPED) {
84         runningState_ = RunningState::STOPPING;
85     }
86 }
87 
Pause()88 void Task::Pause()
89 {
90     OSAL::ScopedLock lock(stateMutex_);
91     RunningState state = runningState_.load();
92     MEDIA_LOG_I("task " PUBLIC_LOG_S " Pause called, running state = " PUBLIC_LOG_D32, name_.c_str(), state);
93     switch (state) {
94         case RunningState::STARTED: {
95             runningState_ = RunningState::PAUSING;
96             syncCond_.Wait(lock, [this] {
97                 return runningState_.load() == RunningState::PAUSED || runningState_.load() == RunningState::STOPPED;
98             });
99             break;
100         }
101         case RunningState::STOPPING: {
102             syncCond_.Wait(lock, [this] { return runningState_.load() == RunningState::STOPPED; });
103             break;
104         }
105         case RunningState::PAUSING: {
106             syncCond_.Wait(lock, [this] { return runningState_.load() == RunningState::PAUSED; });
107             break;
108         }
109         default:
110             break;
111     }
112     MEDIA_LOG_I("task " PUBLIC_LOG_S " Pause done.", name_.c_str());
113 }
114 
PauseAsync()115 void Task::PauseAsync()
116 {
117     MEDIA_LOG_I("task " PUBLIC_LOG_S " PauseAsync called", name_.c_str());
118     OSAL::ScopedLock lock(stateMutex_);
119     if (runningState_.load() == RunningState::STARTED) {
120         runningState_ = RunningState::PAUSING;
121     }
122 }
123 
RegisterHandler(std::function<void ()> handler)124 void Task::RegisterHandler(std::function<void()> handler)
125 {
126     MEDIA_LOG_D("task " PUBLIC_LOG_S " RegisterHandler called", name_.c_str());
127     handler_ = std::move(handler);
128 }
129 
DoTask()130 void Task::DoTask()
131 {
132     MEDIA_LOG_D("task " PUBLIC_LOG_S " not override DoTask...", name_.c_str());
133 }
134 
Run()135 void Task::Run()
136 {
137     for (;;) {
138         MEDIA_LOG_DD("task " PUBLIC_LOG_S " is running on state : " PUBLIC_LOG_D32,
139                      name_.c_str(), runningState_.load());
140         if (runningState_.load() == RunningState::STARTED) {
141             handler_();
142         }
143         OSAL::ScopedLock lock(stateMutex_);
144         if (runningState_.load() == RunningState::PAUSING || runningState_.load() == RunningState::PAUSED) {
145             runningState_ = RunningState::PAUSED;
146             syncCond_.NotifyAll();
147             constexpr int timeoutMs = 500;
148             syncCond_.WaitFor(lock, timeoutMs, [this] { return runningState_.load() != RunningState::PAUSED; });
149         }
150         if (runningState_.load() == RunningState::STOPPING || runningState_.load() == RunningState::STOPPED) {
151             MEDIA_LOG_I("task " PUBLIC_LOG_S " is stopped", name_.c_str());
152             runningState_ = RunningState::STOPPED;
153             syncCond_.NotifyAll();
154             break;
155         }
156     }
157 }
158 } // namespace OSAL
159 } // namespace Media
160 } // namespace OHOS
161