1 /*
2  * Copyright 2019 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 #pragma once
18 
19 #include <chrono>
20 #include <condition_variable>
21 #include <mutex>
22 #include <queue>
23 
24 namespace bluetooth {
25 namespace common {
26 
27 template <typename T>
28 class BlockingQueue {
29  public:
push(T data)30   void push(T data) {
31     std::unique_lock<std::mutex> lock(mutex_);
32     queue_.push(std::move(data));
33     if (queue_.size() == 1) {
34       not_empty_.notify_all();
35     }
36   };
37 
take()38   T take() {
39     std::unique_lock<std::mutex> lock(mutex_);
40     while (queue_.empty()) {
41       not_empty_.wait(lock);
42     }
43     T data = queue_.front();
44     queue_.pop();
45     return data;
46   };
47 
48   // Returns true if take() will not block within a time period
wait_to_take(std::chrono::milliseconds time)49   bool wait_to_take(std::chrono::milliseconds time) {
50     std::unique_lock<std::mutex> lock(mutex_);
51     while (queue_.empty()) {
52       if (not_empty_.wait_for(lock, time) == std::cv_status::timeout) {
53         return false;
54       }
55     }
56     return true;
57   }
58 
empty()59   bool empty() const {
60     std::unique_lock<std::mutex> lock(mutex_);
61     return queue_.empty();
62   };
63 
clear()64   void clear() {
65     std::unique_lock<std::mutex> lock(mutex_);
66     std::queue<T> empty;
67     std::swap(queue_, empty);
68   };
69 
70  private:
71   std::queue<T> queue_;
72   mutable std::mutex mutex_;
73   std::condition_variable not_empty_;
74 };
75 
76 }  // namespace common
77 }  // namespace bluetooth
78