blob: efb04e01a17f4ac427dd171f43872e5264bad0a5 [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
48private:
49 std::condition_variable mCondition;
50 std::mutex mMutex;
51 std::queue<T> mQueue;
Yifan Hong6f667542017-03-20 19:04:05 -070052 const size_t mQueueLimit;
Steven Moreland7e3a2a22016-09-15 09:04:37 -070053};
54
55template <typename T>
Yifan Hong6f667542017-03-20 19:04:05 -070056SynchronizedQueue<T>::SynchronizedQueue(size_t limit) : mQueueLimit(limit) {
57}
58
59template <typename T>
Steven Moreland7e3a2a22016-09-15 09:04:37 -070060T SynchronizedQueue<T>::wait_pop() {
61 std::unique_lock<std::mutex> lock(mMutex);
62
63 mCondition.wait(lock, [this]{
64 return !this->mQueue.empty();
65 });
66
67 T item = mQueue.front();
68 mQueue.pop();
69
70 return item;
71}
72
73template <typename T>
Yifan Hong5e2318c2016-10-27 17:19:21 -070074bool SynchronizedQueue<T>::push(const T &item) {
75 bool success;
Steven Moreland7e3a2a22016-09-15 09:04:37 -070076 {
77 std::unique_lock<std::mutex> lock(mMutex);
Yifan Hong5e2318c2016-10-27 17:19:21 -070078 if (mQueue.size() < mQueueLimit) {
79 mQueue.push(item);
80 success = true;
81 } else {
82 success = false;
83 }
Steven Moreland7e3a2a22016-09-15 09:04:37 -070084 }
85
86 mCondition.notify_one();
Yifan Hong5e2318c2016-10-27 17:19:21 -070087 return success;
Steven Moreland7e3a2a22016-09-15 09:04:37 -070088}
89
90template <typename T>
91size_t SynchronizedQueue<T>::size() {
92 std::unique_lock<std::mutex> lock(mMutex);
93
94 return mQueue.size();
Yifan Hongb93f0502016-10-28 10:42:57 -070095}
Yifan Hong5e2318c2016-10-27 17:19:21 -070096
Yifan Hong0a351392017-03-20 17:17:52 -070097} // namespace details
Yifan Hong5e2318c2016-10-27 17:19:21 -070098} // namespace hardware
99} // namespace android
100
Yifan Hong0a351392017-03-20 17:17:52 -0700101#endif // ANDROID_HIDL_SYNCHRONIZED_QUEUE_H