1*8222fbe1SAndroid Build Coastguard Worker /* 2*8222fbe1SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*8222fbe1SAndroid Build Coastguard Worker * 4*8222fbe1SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*8222fbe1SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*8222fbe1SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*8222fbe1SAndroid Build Coastguard Worker * 8*8222fbe1SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*8222fbe1SAndroid Build Coastguard Worker * 10*8222fbe1SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*8222fbe1SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*8222fbe1SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*8222fbe1SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*8222fbe1SAndroid Build Coastguard Worker * limitations under the License. 15*8222fbe1SAndroid Build Coastguard Worker */ 16*8222fbe1SAndroid Build Coastguard Worker 17*8222fbe1SAndroid Build Coastguard Worker #ifndef ANDROID_HIDL_SYNCHRONIZED_QUEUE_H 18*8222fbe1SAndroid Build Coastguard Worker #define ANDROID_HIDL_SYNCHRONIZED_QUEUE_H 19*8222fbe1SAndroid Build Coastguard Worker 20*8222fbe1SAndroid Build Coastguard Worker #include <condition_variable> 21*8222fbe1SAndroid Build Coastguard Worker #include <mutex> 22*8222fbe1SAndroid Build Coastguard Worker #include <queue> 23*8222fbe1SAndroid Build Coastguard Worker #include <thread> 24*8222fbe1SAndroid Build Coastguard Worker 25*8222fbe1SAndroid Build Coastguard Worker namespace android { 26*8222fbe1SAndroid Build Coastguard Worker namespace hardware { 27*8222fbe1SAndroid Build Coastguard Worker namespace details { 28*8222fbe1SAndroid Build Coastguard Worker /* Threadsafe queue. 29*8222fbe1SAndroid Build Coastguard Worker */ 30*8222fbe1SAndroid Build Coastguard Worker template <typename T> 31*8222fbe1SAndroid Build Coastguard Worker struct SynchronizedQueue { 32*8222fbe1SAndroid Build Coastguard Worker SynchronizedQueue(size_t limit); 33*8222fbe1SAndroid Build Coastguard Worker 34*8222fbe1SAndroid Build Coastguard Worker /* Gets an item from the front of the queue. 35*8222fbe1SAndroid Build Coastguard Worker * 36*8222fbe1SAndroid Build Coastguard Worker * Blocks until the item is available. 37*8222fbe1SAndroid Build Coastguard Worker */ 38*8222fbe1SAndroid Build Coastguard Worker T wait_pop(); 39*8222fbe1SAndroid Build Coastguard Worker 40*8222fbe1SAndroid Build Coastguard Worker /* Puts an item onto the end of the queue. 41*8222fbe1SAndroid Build Coastguard Worker */ 42*8222fbe1SAndroid Build Coastguard Worker bool push(const T& item); 43*8222fbe1SAndroid Build Coastguard Worker 44*8222fbe1SAndroid Build Coastguard Worker /* Gets the size of the array. 45*8222fbe1SAndroid Build Coastguard Worker */ 46*8222fbe1SAndroid Build Coastguard Worker size_t size(); 47*8222fbe1SAndroid Build Coastguard Worker lockSynchronizedQueue48*8222fbe1SAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock() { 49*8222fbe1SAndroid Build Coastguard Worker return std::unique_lock<std::mutex>(mMutex); 50*8222fbe1SAndroid Build Coastguard Worker } 51*8222fbe1SAndroid Build Coastguard Worker isInitializedLockedSynchronizedQueue52*8222fbe1SAndroid Build Coastguard Worker bool isInitializedLocked() { 53*8222fbe1SAndroid Build Coastguard Worker return mInitialized; 54*8222fbe1SAndroid Build Coastguard Worker } setInitializedLockedSynchronizedQueue55*8222fbe1SAndroid Build Coastguard Worker void setInitializedLocked(bool isInitialized) { 56*8222fbe1SAndroid Build Coastguard Worker mInitialized = isInitialized; 57*8222fbe1SAndroid Build Coastguard Worker } 58*8222fbe1SAndroid Build Coastguard Worker 59*8222fbe1SAndroid Build Coastguard Worker private: 60*8222fbe1SAndroid Build Coastguard Worker std::condition_variable mCondition; 61*8222fbe1SAndroid Build Coastguard Worker std::mutex mMutex; 62*8222fbe1SAndroid Build Coastguard Worker std::queue<T> mQueue; 63*8222fbe1SAndroid Build Coastguard Worker const size_t mQueueLimit; 64*8222fbe1SAndroid Build Coastguard Worker bool mInitialized = false; 65*8222fbe1SAndroid Build Coastguard Worker }; 66*8222fbe1SAndroid Build Coastguard Worker 67*8222fbe1SAndroid Build Coastguard Worker template <typename T> SynchronizedQueue(size_t limit)68*8222fbe1SAndroid Build Coastguard WorkerSynchronizedQueue<T>::SynchronizedQueue(size_t limit) : mQueueLimit(limit) { 69*8222fbe1SAndroid Build Coastguard Worker } 70*8222fbe1SAndroid Build Coastguard Worker 71*8222fbe1SAndroid Build Coastguard Worker template <typename T> wait_pop()72*8222fbe1SAndroid Build Coastguard WorkerT SynchronizedQueue<T>::wait_pop() { 73*8222fbe1SAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mMutex); 74*8222fbe1SAndroid Build Coastguard Worker 75*8222fbe1SAndroid Build Coastguard Worker mCondition.wait(lock, [this]{ 76*8222fbe1SAndroid Build Coastguard Worker return !this->mQueue.empty(); 77*8222fbe1SAndroid Build Coastguard Worker }); 78*8222fbe1SAndroid Build Coastguard Worker 79*8222fbe1SAndroid Build Coastguard Worker T item = mQueue.front(); 80*8222fbe1SAndroid Build Coastguard Worker mQueue.pop(); 81*8222fbe1SAndroid Build Coastguard Worker 82*8222fbe1SAndroid Build Coastguard Worker return item; 83*8222fbe1SAndroid Build Coastguard Worker } 84*8222fbe1SAndroid Build Coastguard Worker 85*8222fbe1SAndroid Build Coastguard Worker template <typename T> push(const T & item)86*8222fbe1SAndroid Build Coastguard Workerbool SynchronizedQueue<T>::push(const T &item) { 87*8222fbe1SAndroid Build Coastguard Worker bool success; 88*8222fbe1SAndroid Build Coastguard Worker { 89*8222fbe1SAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mMutex); 90*8222fbe1SAndroid Build Coastguard Worker if (mQueue.size() < mQueueLimit) { 91*8222fbe1SAndroid Build Coastguard Worker mQueue.push(item); 92*8222fbe1SAndroid Build Coastguard Worker success = true; 93*8222fbe1SAndroid Build Coastguard Worker } else { 94*8222fbe1SAndroid Build Coastguard Worker success = false; 95*8222fbe1SAndroid Build Coastguard Worker } 96*8222fbe1SAndroid Build Coastguard Worker } 97*8222fbe1SAndroid Build Coastguard Worker 98*8222fbe1SAndroid Build Coastguard Worker mCondition.notify_one(); 99*8222fbe1SAndroid Build Coastguard Worker return success; 100*8222fbe1SAndroid Build Coastguard Worker } 101*8222fbe1SAndroid Build Coastguard Worker 102*8222fbe1SAndroid Build Coastguard Worker template <typename T> size()103*8222fbe1SAndroid Build Coastguard Workersize_t SynchronizedQueue<T>::size() { 104*8222fbe1SAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mMutex); 105*8222fbe1SAndroid Build Coastguard Worker 106*8222fbe1SAndroid Build Coastguard Worker return mQueue.size(); 107*8222fbe1SAndroid Build Coastguard Worker } 108*8222fbe1SAndroid Build Coastguard Worker 109*8222fbe1SAndroid Build Coastguard Worker } // namespace details 110*8222fbe1SAndroid Build Coastguard Worker } // namespace hardware 111*8222fbe1SAndroid Build Coastguard Worker } // namespace android 112*8222fbe1SAndroid Build Coastguard Worker 113*8222fbe1SAndroid Build Coastguard Worker #endif // ANDROID_HIDL_SYNCHRONIZED_QUEUE_H 114