Home | History | Annotate | Download | only in hidl
      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>
     56 SynchronizedQueue<T>::SynchronizedQueue(size_t limit) : mQueueLimit(limit) {
     57 }
     58 
     59 template <typename T>
     60 T 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>
     74 bool 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>
     91 size_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