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 
27 namespace chre {
28 
29 /**
30  * Implements a thread-safe blocking queue that blocks when popping an element
31  * if necessary.
32  */
33 template <typename ElementType, size_t kSize>
34 class FixedSizeBlockingQueue : public NonCopyable {
35  public:
36   /**
37    * Pushes an element into the queue and notifies any waiting threads that an
38    * element is available.
39    *
40    * @param The element to be pushed.
41    *
42    * @return true if the element is pushed successfully.
43    */
44   bool push(const ElementType& element);
45   bool push(ElementType&& element);
46 
47   /**
48    * Pops one element from the queue. If the queue is empty, the thread will
49    * block until an element has been pushed.
50    *
51    * @return The element that was popped.
52    */
53   ElementType pop();
54 
55   /**
56    * Determines whether or not the BlockingQueue is empty.
57    */
58   bool empty();
59 
60   /**
61    * Determines the current size of the BlockingQueue.
62    */
63   size_t size();
64 
65   /**
66    * Removes an element from the array queue given an index. It returns false if
67    * the index is out of bounds of the underlying array queue.
68    *
69    * @param index Requested index in range [0,size()-1]
70    * @return true if the indexed element has been removed successfully.
71    */
72   bool remove(size_t index);
73 
74   /**
75    * Obtains an element of the array queue given an index. It is illegal to
76    * index this array queue out of bounds and the user of the API must check the
77    * size() function prior to indexing this array queue to ensure that they will
78    * not read out of bounds.
79    *
80    * @param index Requested index in range [0,size()-1]
81    * @return The element.
82    */
83   ElementType& operator[](size_t index);
84 
85   /**
86    * Obtains a const element of the queue given an index. It is illegal to index
87    * this queue out of bounds and the user of the API must check the size()
88    * function prior to indexing this queue to ensure that they will not read out
89    * of bounds.
90    *
91    * @param index Requested index in the rante [0,size()-1]
92    * @return The element.
93    */
94   const ElementType& operator[](size_t index) const;
95 
96  private:
97   //! The mutex used to ensure thread-safety.
98   Mutex mMutex;
99 
100   //! The condition variable used to implement the blocking behavior of the
101   //! queue.
102   ConditionVariable mConditionVariable;
103 
104   //! The underlying fixed size container backing the queue.
105   ArrayQueue<ElementType, kSize> mQueue;
106 };
107 
108 }  // namespace chre
109 
110 #include "chre/util/fixed_size_blocking_queue_impl.h"
111 
112 #endif  // CHRE_UTIL_FIXED_SIZE_BLOCKING_QUEUE_H_
113