blob: 356c72caed9371547e5f42f758c21e470de2b2c3 [file] [log] [blame]
Yifan Hongb93f0502016-10-28 10:42:57 -07001/*
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
Yifan Hong0a351392017-03-20 17:17:52 -070017#ifndef ANDROID_HIDL_SYNCHRONIZED_QUEUE_H
18#define ANDROID_HIDL_SYNCHRONIZED_QUEUE_H
Yifan Hong5e2318c2016-10-27 17:19:21 -070019
Steven Moreland7e3a2a22016-09-15 09:04:37 -070020#include <condition_variable>
21#include <mutex>
22#include <queue>
23#include <thread>
24
Yifan Hong5e2318c2016-10-27 17:19:21 -070025namespace android {
26namespace hardware {
Yifan Hong0a351392017-03-20 17:17:52 -070027namespace details {
Steven Moreland7e3a2a22016-09-15 09:04:37 -070028/* Threadsafe queue.
29 */
30template <typename T>
31struct SynchronizedQueue {
Yifan Hong6f667542017-03-20 19:04:05 -070032 SynchronizedQueue(size_t limit);
Steven Moreland7e3a2a22016-09-15 09:04:37 -070033
34 /* Gets an item from the front of the queue.
35 *
36 * Blocks until the item is available.
37 */
38 T wait_pop();
39
40 /* Puts an item onto the end of the queue.
41 */
Yifan Hong5e2318c2016-10-27 17:19:21 -070042 bool push(const T& item);
Steven Moreland7e3a2a22016-09-15 09:04:37 -070043
44 /* Gets the size of the array.
45 */
46 size_t size();
47
Steven Morelandc03f9432017-08-16 14:17:49 -070048 std::unique_lock<std::mutex> lock() {
49 return std::unique_lock<std::mutex>(mMutex);
50 }
51
52 bool isInitializedLocked() {
53 return mInitialized;
54 }
55 void setInitializedLocked(bool isInitialized) {
56 mInitialized = isInitialized;
57 }
58
Steven Moreland7e3a2a22016-09-15 09:04:37 -070059private:
60 std::condition_variable mCondition;
61 std::mutex mMutex;
62 std::queue<T> mQueue;
Yifan Hong6f667542017-03-20 19:04:05 -070063 const size_t mQueueLimit;
Steven Moreland0dab3262017-10-05 16:52:29 -070064 bool mInitialized = false;
Steven Moreland7e3a2a22016-09-15 09:04:37 -070065};
66
67template <typename T>
Yifan Hong6f667542017-03-20 19:04:05 -070068SynchronizedQueue<T>::SynchronizedQueue(size_t limit) : mQueueLimit(limit) {
69}
70
71template <typename T>
Steven Moreland7e3a2a22016-09-15 09:04:37 -070072T SynchronizedQueue<T>::wait_pop() {
73 std::unique_lock<std::mutex> lock(mMutex);
74
75 mCondition.wait(lock, [this]{
76 return !this->mQueue.empty();
77 });
78
79 T item = mQueue.front();
80 mQueue.pop();
81
82 return item;
83}
84
85template <typename T>
Yifan Hong5e2318c2016-10-27 17:19:21 -070086bool SynchronizedQueue<T>::push(const T &item) {
87 bool success;
Steven Moreland7e3a2a22016-09-15 09:04:37 -070088 {
89 std::unique_lock<std::mutex> lock(mMutex);
Yifan Hong5e2318c2016-10-27 17:19:21 -070090 if (mQueue.size() < mQueueLimit) {
91 mQueue.push(item);
92 success = true;
93 } else {
94 success = false;
95 }
Steven Moreland7e3a2a22016-09-15 09:04:37 -070096 }
97
98 mCondition.notify_one();
Yifan Hong5e2318c2016-10-27 17:19:21 -070099 return success;
Steven Moreland7e3a2a22016-09-15 09:04:37 -0700100}
101
102template <typename T>
103size_t SynchronizedQueue<T>::size() {
104 std::unique_lock<std::mutex> lock(mMutex);
105
106 return mQueue.size();
Yifan Hongb93f0502016-10-28 10:42:57 -0700107}
Yifan Hong5e2318c2016-10-27 17:19:21 -0700108
Yifan Hong0a351392017-03-20 17:17:52 -0700109} // namespace details
Yifan Hong5e2318c2016-10-27 17:19:21 -0700110} // namespace hardware
111} // namespace android
112
Yifan Hong0a351392017-03-20 17:17:52 -0700113#endif // ANDROID_HIDL_SYNCHRONIZED_QUEUE_H