Android-cuttlefish cvd tool
thread_safe_queue.h
Go to the documentation of this file.
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#pragma once
18
19#include <stddef.h>
20
21#include <condition_variable>
22#include <deque>
23#include <functional>
24#include <mutex>
25#include <type_traits>
26#include <utility>
27
28namespace cuttlefish {
29// Simple queue with Push and Pop capabilities.
30// If the max_elements argument is passed to the constructor, and Push is called
31// when the queue holds max_elements items, the max_elements_handler is called
32// with a pointer to the internal QueueImpl. The call is made while holding
33// the guarding mutex; operations on the QueueImpl will not interleave with
34// other threads calling Push() or Pop().
35// The QueueImpl type will be a SequenceContainer.
36template <typename T>
38 public:
39 using QueueImpl = std::deque<T>;
40 using QueueFullHandler = std::function<void(QueueImpl*)>;
41
42 ThreadSafeQueue() = default;
43 explicit ThreadSafeQueue(size_t max_elements,
44 QueueFullHandler max_elements_handler)
45 : max_elements_{max_elements},
46 max_elements_handler_{std::move(max_elements_handler)} {}
47
48 T Pop() {
49 std::unique_lock<std::mutex> guard(m_);
50 while (items_.empty()) {
51 new_item_.wait(guard);
52 }
53 auto t = std::move(items_.front());
54 items_.pop_front();
55 return t;
56 }
57
59 std::unique_lock<std::mutex> guard(m_);
60 while (items_.empty()) {
61 new_item_.wait(guard);
62 }
63 return std::move(items_);
64 }
65
66 template <typename U>
67 bool Push(U&& u) {
68 static_assert(std::is_assignable_v<T, decltype(u)>);
69 std::lock_guard<std::mutex> guard(m_);
70 const bool has_room = DropItemsIfAtCapacity();
71 if (!has_room) {
72 return false;
73 }
74 items_.push_back(std::forward<U>(u));
75 new_item_.notify_one();
76 return true;
77 }
78
79 bool IsEmpty() {
80 std::lock_guard<std::mutex> guard(m_);
81 return items_.empty();
82 }
83
84 bool IsFull() {
85 std::lock_guard<std::mutex> guard(m_);
86 return items_.size() == max_elements_;
87 }
88
89 private:
90 // return whether there's room to push
92 if (max_elements_ && max_elements_ == items_.size()) {
94 }
95 if (max_elements_ && max_elements_ == items_.size()) {
96 // handler intends to ignore the newly coming element or
97 // did not empty the room for whatever reason
98 return false;
99 }
100 return true;
101 }
102
103 std::mutex m_;
106 std::condition_variable new_item_;
108};
109} // namespace cuttlefish
Definition: thread_safe_queue.h:37
QueueFullHandler max_elements_handler_
Definition: thread_safe_queue.h:105
std::deque< T > QueueImpl
Definition: thread_safe_queue.h:39
ThreadSafeQueue(size_t max_elements, QueueFullHandler max_elements_handler)
Definition: thread_safe_queue.h:43
bool IsEmpty()
Definition: thread_safe_queue.h:79
QueueImpl items_
Definition: thread_safe_queue.h:107
QueueImpl PopAll()
Definition: thread_safe_queue.h:58
bool Push(U &&u)
Definition: thread_safe_queue.h:67
std::condition_variable new_item_
Definition: thread_safe_queue.h:106
T Pop()
Definition: thread_safe_queue.h:48
size_t max_elements_
Definition: thread_safe_queue.h:104
bool DropItemsIfAtCapacity()
Definition: thread_safe_queue.h:91
bool IsFull()
Definition: thread_safe_queue.h:84
std::mutex m_
Definition: thread_safe_queue.h:103
std::function< void(QueueImpl *)> QueueFullHandler
Definition: thread_safe_queue.h:40
Definition: alloc_driver.h:20
Definition: logging.h:464