1 // Copyright (C) 2016 The Android Open Source Project
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #include "anbox/graphics/buffer_queue.h"
19 BufferQueue::BufferQueue(size_t capacity)
20 : capacity_(capacity), buffers_(new Buffer[capacity]) {}
22 int BufferQueue::try_push_locked(Buffer &&buffer) {
26 if (count_ >= capacity_)
29 size_t pos = pos_ + count_;
33 buffers_[pos] = std::move(buffer);
35 can_pop_.notify_one();
40 int BufferQueue::push_locked(
41 Buffer &&buffer, std::unique_lock<std::mutex> &lock) {
42 while (count_ == capacity_) {
47 return try_push_locked(std::move(buffer));
50 int BufferQueue::wait_until_not_empty_locked(std::unique_lock<std::mutex> &lock) {
53 // Closed queue is empty.
61 int BufferQueue::try_pop_locked(Buffer *buffer) {
63 return closed_ ? -EIO : -EAGAIN;
65 *buffer = std::move(buffers_[pos_]);
66 size_t pos = pos_ + 1;
71 if (count_-- == capacity_)
72 can_push_.notify_one();
77 int BufferQueue::pop_locked(
78 Buffer *buffer, std::unique_lock<std::mutex> &lock) {
81 // Closed queue is empty.
85 return try_pop_locked(buffer);
88 // Close the queue, it is no longer possible to push new items
89 // to it (i.e. push() will always return Result::Error), or to
90 // read from an empty queue (i.e. pop() will always return
91 // Result::Error once the queue becomes empty).
92 void BufferQueue::close_locked() {
95 // Wake any potential waiters.
96 if (count_ == capacity_) {
97 can_push_.notify_all();
100 can_pop_.notify_all();
103 } // namespace graphics