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 CHRE_UTIL_FIXED_SIZE_BLOCKING_QUEUE_H_ 18 #define CHRE_UTIL_FIXED_SIZE_BLOCKING_QUEUE_H_ 19 20 #include <deque> 21 22 #include "chre/platform/condition_variable.h" 23 #include "chre/platform/mutex.h" 24 #include "chre/util/array_queue.h" 25 #include "chre/util/non_copyable.h" 26 #include "chre/util/segmented_queue.h" 27 28 namespace chre { 29 30 namespace blocking_queue_internal { 31 32 /** 33 * The wrapper around queue storage (ArraryQueue or SegmentedQueue) that 34 * provide thread safety. 35 * 36 * The queue storage must provide the following APIs: 37 * empty(), size(), push(), front(), pop(), remove(), operator[]. 38 */ 39 template <typename ElementType, class QueueStorageType> 40 class BlockingQueueCore : public QueueStorageType { 41 public: 42 // Inherit constructors from QueueStorageType 43 using QueueStorageType::QueueStorageType; 44 45 /** 46 * Determines whether or not the BlockingQueue is empty. 47 */ 48 bool empty(); 49 50 /** 51 * Determines the current size of the BlockingQueue. 52 */ 53 size_t size(); 54 55 /** 56 * Pushes an element into the queue and notifies any waiting threads that an 57 * element is available. 58 * 59 * @param The element to be pushed. 60 * @return true if the element is pushed successfully. 61 */ 62 bool push(const ElementType &element); 63 bool push(ElementType &&element); 64 65 /** 66 * Pops one element from the queue. If the queue is empty, the thread will 67 * block until an element has been pushed. 68 * 69 * @return The element that was popped. 70 */ 71 ElementType pop(); 72 73 /** 74 * Removes an element from the array queue given an index. It returns false if 75 * the index is out of bounds of the underlying array queue. 76 * 77 * @param index Requested index in range [0,size()-1] 78 * @return true if the indexed element has been removed successfully. 79 */ 80 bool remove(size_t index); 81 82 /** 83 * Obtains an element of the array queue given an index. It is illegal to 84 * index this array queue out of bounds and the user of the API must check 85 * the size() function prior to indexing this array queue to ensure that they 86 * will not read out of bounds. 87 * 88 * @param index Requested index in range [0,size()-1] 89 * @return The element. 90 */ 91 ElementType &operator[](size_t index); 92 const ElementType &operator[](size_t index) const; 93 94 protected: 95 //! The mutex used to ensure thread-safety. Mutable to allow const 96 //! operator[]. 97 mutable Mutex mMutex; 98 99 private: 100 //! The condition variable used to implement the blocking behavior of the 101 //! queue. 102 ConditionVariable mConditionVariable; 103 }; 104 } // namespace blocking_queue_internal 105 106 /** 107 * Wrapper for the blocking queue implementation that uses chre::ArrayQueue as 108 * the data container. 109 * 110 * @tparam ElementType type of the item that will be stored in the queue. 111 * @tparam kSize maximum item count that this queue can hold 112 */ 113 template <typename ElementType, size_t kSize> 114 class FixedSizeBlockingQueue 115 : public blocking_queue_internal::BlockingQueueCore< 116 ElementType, ArrayQueue<ElementType, kSize>> { 117 public: 118 typedef ElementType value_type; 119 }; 120 121 } // namespace chre 122 123 #include "chre/util/fixed_size_blocking_queue_impl.h" 124 125 #endif // CHRE_UTIL_FIXED_SIZE_BLOCKING_QUEUE_H_ 126