1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <hidl/TaskRunner.h>
18 
19 #include <utils/AndroidThreads.h>
20 #include "SynchronizedQueue.h"
21 
22 #include <thread>
23 
24 namespace android {
25 namespace hardware {
26 namespace details {
27 
28 TaskRunner::TaskRunner() {
29 }
30 
31 void TaskRunner::start(size_t limit) {
32     mQueue = std::make_shared<SynchronizedQueue<Task>>(limit);
33 }
34 
35 TaskRunner::~TaskRunner() {
36     if (mQueue) {
37         mQueue->push(nullptr);
38     }
39 }
40 
41 bool TaskRunner::push(const Task &t) {
42     if (mQueue == nullptr || !t) {
43         return false;
44     }
45 
46     {
47         std::unique_lock<std::mutex> lock = mQueue->lock();
48 
49         if (!mQueue->isInitializedLocked()) {
50             // Allow the thread to continue running in background;
51             // TaskRunner do not care about the std::thread object.
52             std::thread{[q = mQueue] {
53                 androidSetThreadName("HIDL TaskRunner");
54 
55                 Task nextTask;
56                 while (!!(nextTask = q->wait_pop())) {
57                     nextTask();
58                 }
59             }}.detach();
60 
61             mQueue->setInitializedLocked(true);
62         }
63     }
64 
65     return this->mQueue->push(t);
66 }
67 
68 } // namespace details
69 } // namespace hardware
70 } // namespace android
71 
72