1 /*
2 * Copyright (C) 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
16 #include "dispatcher.h"
17 #include "log.h"
18
19 namespace utility {
EmptyTask()20 static void EmptyTask()
21 {}
22
Dispatcher(const std::string & name)23 Dispatcher::Dispatcher(const std::string &name) : name_(name), taskQueue_(128)
24 {}
25
~Dispatcher()26 Dispatcher::~Dispatcher()
27 {}
28
Initialize()29 void Dispatcher::Initialize()
30 {
31 std::lock_guard<std::mutex> lock(mutex_);
32 if (!start_) {
33 start_ = true;
34 std::promise<void> startPromise;
35 std::future<void> startFuture = startPromise.get_future();
36 thread_ = std::make_unique<std::thread>(&Dispatcher::Run, this, std::move(startPromise));
37 startFuture.wait();
38 }
39 }
40
Uninitialize()41 void Dispatcher::Uninitialize()
42 {
43 std::lock_guard<std::mutex> lock(mutex_);
44 if (start_) {
45 start_ = false;
46 taskQueue_.Push(std::bind(EmptyTask));
47 if (thread_ && thread_->joinable()) {
48 thread_->join();
49 thread_ = nullptr;
50 }
51 }
52 }
53
PostTask(const std::function<void ()> & task)54 void Dispatcher::PostTask(const std::function<void()> &task)
55 {
56 if (start_) {
57 if (!taskQueue_.TryPush(std::move(task))) {
58 LOG_ERROR("%{public}s Dispatcher::PostTask failed!", name_.c_str());
59 }
60 }
61 }
62
Name() const63 const std::string &Dispatcher::Name() const
64 {
65 return name_;
66 }
67
Run(std::promise<void> promise)68 void Dispatcher::Run(std::promise<void> promise)
69 {
70 pthread_setname_np(pthread_self(), name_.c_str());
71 promise.set_value();
72
73 while (start_) {
74 std::function<void()> task;
75 taskQueue_.Pop(task);
76 task();
77 }
78
79 // If there are tasks in the queue. will not execute them.
80 }
81 } // namespace utility