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