Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: content/common/message_port.cc

Issue 2422793002: HTML MessagePort as mojo::MessagePipeHandle (Closed)
Patch Set: Add missing ScopedAsyncTaskScheduler instance for the new unit tests; required by a recent change t… Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/message_port.h ('k') | content/common/message_port_messages.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/message_port.cc
diff --git a/content/common/message_port.cc b/content/common/message_port.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c89d7b5a0d0cc313290329602fedc13e6dff9150
--- /dev/null
+++ b/content/common/message_port.cc
@@ -0,0 +1,186 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/message_port.h"
+
+#include "base/logging.h"
+
+namespace content {
+
+MessagePort::~MessagePort() {
+}
+
+MessagePort::MessagePort() : state_(new State()) {
+}
+
+MessagePort::MessagePort(const MessagePort& other) : state_(other.state_) {
+}
+
+MessagePort& MessagePort::operator=(const MessagePort& other) {
+ state_ = other.state_;
+ return *this;
+}
+
+MessagePort::MessagePort(mojo::ScopedMessagePipeHandle handle)
+ : state_(new State(std::move(handle))) {
+}
+
+const mojo::ScopedMessagePipeHandle& MessagePort::GetHandle() const {
+ return state_->handle_;
+}
+
+mojo::ScopedMessagePipeHandle MessagePort::ReleaseHandle() const {
+ state_->CancelWatch();
+ return std::move(state_->handle_);
+}
+
+// static
+std::vector<mojo::ScopedMessagePipeHandle> MessagePort::ReleaseHandles(
+ const std::vector<MessagePort>& ports) {
+ std::vector<mojo::ScopedMessagePipeHandle> handles(ports.size());
+ for (size_t i = 0; i < ports.size(); ++i)
+ handles[i] = ports[i].ReleaseHandle();
+ return handles;
+}
+
+void MessagePort::PostMessage(const base::string16& encoded_message,
+ std::vector<MessagePort> ports) {
+ DCHECK(state_->handle_.is_valid());
+
+ uint32_t num_bytes = encoded_message.size() * sizeof(base::char16);
+
+ // NOTE: It is OK to ignore the return value of MojoWriteMessage here. HTML
+ // MessagePorts have no way of reporting when the peer is gone.
+
+ if (ports.empty()) {
+ MojoWriteMessage(state_->handle_.get().value(),
+ encoded_message.data(),
+ num_bytes,
+ nullptr,
+ 0,
+ MOJO_WRITE_MESSAGE_FLAG_NONE);
+ } else {
+ uint32_t num_handles = static_cast<uint32_t>(ports.size());
+ std::unique_ptr<MojoHandle[]> handles(new MojoHandle[num_handles]);
+ for (uint32_t i = 0; i < num_handles; ++i)
+ handles[i] = ports[i].ReleaseHandle().release().value();
+ MojoWriteMessage(state_->handle_.get().value(),
+ encoded_message.data(),
+ num_bytes,
+ handles.get(),
+ num_handles,
+ MOJO_WRITE_MESSAGE_FLAG_NONE);
+ }
+}
+
+bool MessagePort::GetMessage(base::string16* encoded_message,
+ std::vector<MessagePort>* ports) {
+ DCHECK(state_->handle_.is_valid());
+
+ uint32_t num_bytes = 0;
+ uint32_t num_handles = 0;
+
+ MojoResult rv = MojoReadMessage(state_->handle_.get().value(),
+ nullptr,
+ &num_bytes,
+ nullptr,
+ &num_handles,
+ MOJO_READ_MESSAGE_FLAG_NONE);
+ if (rv == MOJO_RESULT_OK) {
+ encoded_message->clear();
+ ports->clear();
+ return true;
+ }
+ if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED)
+ return false;
+
+ CHECK(num_bytes % 2 == 0);
+
+ base::string16 buffer;
+ buffer.resize(num_bytes / sizeof(base::char16));
+
+ std::unique_ptr<MojoHandle[]> handles;
+ if (num_handles)
+ handles.reset(new MojoHandle[num_handles]);
+
+ rv = MojoReadMessage(state_->handle_.get().value(),
+ num_bytes ? &buffer[0] : nullptr,
+ &num_bytes,
+ handles.get(),
+ &num_handles,
+ MOJO_READ_MESSAGE_FLAG_NONE);
+ if (rv != MOJO_RESULT_OK)
+ return false;
+
+ buffer.swap(*encoded_message);
+
+ if (num_handles) {
+ ports->resize(static_cast<size_t>(num_handles));
+ for (uint32_t i = 0; i < num_handles; ++i) {
+ ports->at(i) = MessagePort(
+ mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handles[i])));
+ }
+ }
+ return true;
+}
+
+void MessagePort::SetCallback(const base::Closure& callback) {
+ state_->CancelWatch();
+ state_->callback_ = callback;
+ state_->AddWatch();
+}
+
+void MessagePort::ClearCallback() {
+ state_->CancelWatch();
+ state_->callback_.Reset();
+}
+
+MessagePort::State::State() {
+}
+
+MessagePort::State::State(mojo::ScopedMessagePipeHandle handle)
+ : handle_(std::move(handle)) {
+}
+
+void MessagePort::State::AddWatch() {
+ if (!callback_)
+ return;
+
+ // NOTE: An HTML MessagePort does not receive an event to tell it when the
+ // peer has gone away, so we only watch for readability here.
+ MojoResult rv = MojoWatch(handle_.get().value(),
+ MOJO_HANDLE_SIGNAL_READABLE,
+ &MessagePort::State::OnHandleReady,
+ reinterpret_cast<uintptr_t>(this));
+ if (rv != MOJO_RESULT_OK)
+ DVLOG(1) << this << " MojoWatch failed: " << rv;
+}
+
+void MessagePort::State::CancelWatch() {
+ if (!callback_)
+ return;
+
+ // NOTE: This synchronizes with the thread where OnHandleReady runs so we are
+ // sure to not be racing with it.
+ MojoCancelWatch(handle_.get().value(), reinterpret_cast<uintptr_t>(this));
+}
+
+// static
+void MessagePort::State::OnHandleReady(
+ uintptr_t context,
+ MojoResult result,
+ MojoHandleSignalsState signals_state,
+ MojoWatchNotificationFlags flags) {
+ if (result == MOJO_RESULT_OK) {
+ reinterpret_cast<MessagePort::State*>(context)->callback_.Run();
+ } else {
+ // And now his watch is ended.
+ }
+}
+
+MessagePort::State::~State() {
+ CancelWatch();
+}
+
+} // namespace content
« no previous file with comments | « content/common/message_port.h ('k') | content/common/message_port_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698