X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Fbuffer_queue.cpp;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Fbuffer_queue.cpp;h=1f18d5ec21cdc2437cfb4d63f9a16dcd1d40b109;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/buffer_queue.cpp b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/buffer_queue.cpp new file mode 100644 index 0000000..1f18d5e --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/buffer_queue.cpp @@ -0,0 +1,104 @@ +// Copyright (C) 2016 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "anbox/graphics/buffer_queue.h" + +namespace anbox { +namespace graphics { +BufferQueue::BufferQueue(size_t capacity) + : capacity_(capacity), buffers_(new Buffer[capacity]) {} + +int BufferQueue::try_push_locked(Buffer &&buffer) { + if (closed_) + return -EIO; + + if (count_ >= capacity_) + return -EAGAIN; + + size_t pos = pos_ + count_; + if (pos >= capacity_) + pos -= capacity_; + + buffers_[pos] = std::move(buffer); + if (count_++ == 0) + can_pop_.notify_one(); + + return 0; +} + +int BufferQueue::push_locked( + Buffer &&buffer, std::unique_lock &lock) { + while (count_ == capacity_) { + if (closed_) + return -EIO; + can_push_.wait(lock); + } + return try_push_locked(std::move(buffer)); +} + +int BufferQueue::wait_until_not_empty_locked(std::unique_lock &lock) { + while (count_ == 0) { + if (closed_) + // Closed queue is empty. + return -EIO; + can_pop_.wait(lock); + } + + return 0; +} + +int BufferQueue::try_pop_locked(Buffer *buffer) { + if (count_ == 0) + return closed_ ? -EIO : -EAGAIN; + + *buffer = std::move(buffers_[pos_]); + size_t pos = pos_ + 1; + if (pos >= capacity_) + pos -= capacity_; + + pos_ = pos; + if (count_-- == capacity_) + can_push_.notify_one(); + + return 0; +} + +int BufferQueue::pop_locked( + Buffer *buffer, std::unique_lock &lock) { + while (count_ == 0) { + if (closed_) + // Closed queue is empty. + return -EIO; + can_pop_.wait(lock); + } + return try_pop_locked(buffer); +} + +// Close the queue, it is no longer possible to push new items +// to it (i.e. push() will always return Result::Error), or to +// read from an empty queue (i.e. pop() will always return +// Result::Error once the queue becomes empty). +void BufferQueue::close_locked() { + closed_ = true; + + // Wake any potential waiters. + if (count_ == capacity_) { + can_push_.notify_all(); + } + if (count_ == 0) { + can_pop_.notify_all(); + } +} +} // namespace graphics +} // namespace anbox