1 /*
2  * Copyright (C) 2023 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 <condition_variable>
20 #include <deque>
21 #include <mutex>
22 #include <optional>
23 
24 namespace android {
25 namespace hardware {
26 namespace camera {
27 namespace provider {
28 namespace implementation {
29 
30 template <class T> struct BlockingQueue {
31     BlockingQueue() = default;
32 
putBlockingQueue33     bool put(T* x)  {
34         std::lock_guard lock(mtx);
35         if (cancelled) {
36             return false;
37         } else {
38             queue.push_back(std::move(*x));
39             available.notify_one();
40             return true;
41         }
42     }
43 
getBlockingQueue44     std::optional<T> get() {
45         std::unique_lock lock(mtx);
46         while (true) {
47             if (!queue.empty()) {
48                 T x = std::move(queue.front());
49                 queue.pop_front();
50                 return x;
51             } else if (cancelled) {
52                 return std::nullopt;
53             } else {
54                 available.wait(lock);
55             }
56         }
57     }
58 
tryGetBlockingQueue59     std::optional<T> tryGet() {
60         std::lock_guard lock(mtx);
61         if (queue.empty()) {
62             return std::nullopt;
63         } else {
64             T x = std::move(queue.front());
65             queue.pop_front();
66             return x;
67         }
68     }
69 
cancelBlockingQueue70     void cancel() {
71         std::lock_guard lock(mtx);
72         cancelled = true;
73         available.notify_one();
74     }
75 
76     BlockingQueue(const BlockingQueue&) = delete;
77     BlockingQueue(BlockingQueue&&) = delete;
78     BlockingQueue& operator=(const BlockingQueue&) = delete;
79     BlockingQueue& operator=(BlockingQueue&&) = delete;
80 
81 private:
82     std::deque<T> queue;
83     std::condition_variable available;
84     bool cancelled = false;
85     std::mutex mtx;
86 };
87 
88 }  // namespace implementation
89 }  // namespace provider
90 }  // namespace camera
91 }  // namespace hardware
92 }  // namespace android
93