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 #ifndef ANDROID_HIDL_SYNCHRONIZED_QUEUE_H 18 #define ANDROID_HIDL_SYNCHRONIZED_QUEUE_H 19 20 #include <condition_variable> 21 #include <mutex> 22 #include <queue> 23 #include <thread> 24 25 namespace android { 26 namespace hardware { 27 namespace details { 28 /* Threadsafe queue. 29 */ 30 template <typename T> 31 struct SynchronizedQueue { 32 SynchronizedQueue(size_t limit); 33 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 */ 42 bool push(const T& item); 43 44 /* Gets the size of the array. 45 */ 46 size_t size(); 47 48 private: 49 std::condition_variable mCondition; 50 std::mutex mMutex; 51 std::queue<T> mQueue; 52 const size_t mQueueLimit; 53 }; 54 55 template <typename T> SynchronizedQueue(size_t limit)56SynchronizedQueue<T>::SynchronizedQueue(size_t limit) : mQueueLimit(limit) { 57 } 58 59 template <typename T> wait_pop()60T 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 73 template <typename T> push(const T & item)74bool SynchronizedQueue<T>::push(const T &item) { 75 bool success; 76 { 77 std::unique_lock<std::mutex> lock(mMutex); 78 if (mQueue.size() < mQueueLimit) { 79 mQueue.push(item); 80 success = true; 81 } else { 82 success = false; 83 } 84 } 85 86 mCondition.notify_one(); 87 return success; 88 } 89 90 template <typename T> size()91size_t SynchronizedQueue<T>::size() { 92 std::unique_lock<std::mutex> lock(mMutex); 93 94 return mQueue.size(); 95 } 96 97 } // namespace details 98 } // namespace hardware 99 } // namespace android 100 101 #endif // ANDROID_HIDL_SYNCHRONIZED_QUEUE_H 102