TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / common / message_channel.h
diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/common/message_channel.h b/src/type3_AndroidCloud/anbox-master/src/anbox/common/message_channel.h
new file mode 100644 (file)
index 0000000..930d92c
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright 2014 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.
+
+#ifndef ANBOX_COMMON_MESSAGE_CHANNEL_H
+#define ANBOX_COMMON_MESSAGE_CHANNEL_H
+
+#include <stddef.h>
+
+#include <condition_variable>
+#include <mutex>
+
+namespace anbox {
+namespace common {
+
+// Base non-templated class used to reduce the amount of template
+// specialization.
+class MessageChannelBase {
+ public:
+  // Constructor. |capacity| is the buffer capacity in messages.
+  MessageChannelBase(size_t capacity);
+
+  // Destructor.
+  ~MessageChannelBase();
+
+ protected:
+  // Call this method in the sender thread before writing a new message.
+  // This returns the position of the available slot in the message array
+  // where to copy the new fixed-size message. After the copy, call
+  // afterWrite().
+  size_t before_write();
+
+  // To be called after beforeWrite() and copying a new fixed-size message
+  // into the array. This signal the receiver thread that there is a new
+  // incoming message.
+  void after_write();
+
+  // Call this method in the receiver thread before reading a new message.
+  // This returns the position in the message array where the new message
+  // can be read. Caller must process the message, then call afterRead().
+  size_t before_read();
+
+  // To be called in the receiver thread after beforeRead() and processing
+  // the corresponding message.
+  void after_read();
+
+ private:
+  size_t pos_;
+  size_t count_;
+  size_t capacity_;
+  std::mutex lock_;
+  std::condition_variable can_read_;
+  std::condition_variable can_write_;
+};
+
+// Helper class used to implement an uni-directional IPC channel between
+// two threads. The channel can be used to send fixed-size messages of type
+// |T|, with an internal buffer size of |CAPACITY| items. All calls are
+// blocking.
+//
+// Usage is pretty straightforward:
+//
+//   - From the sender thread, call send(msg);
+//   - From the receiver thread, call receive(&msg);
+//
+template <typename T, size_t CAPACITY>
+class MessageChannel : public MessageChannelBase {
+ public:
+  MessageChannel() : MessageChannelBase(CAPACITY) {}
+
+  void send(const T& msg) {
+    size_t pos = before_write();
+    mItems[pos] = msg;
+    after_write();
+  }
+
+  void receive(T* msg) {
+    size_t pos = before_read();
+    *msg = mItems[pos];
+    after_read();
+  }
+
+ private:
+  T mItems[CAPACITY];
+};
+}  // namespace common
+}  // namespace anbox
+
+#endif