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