TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / graphics / buffer_queue.cpp
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 (file)
index 0000000..1f18d5e
--- /dev/null
@@ -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<std::mutex> &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<std::mutex> &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<std::mutex> &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