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

Unified Diff: ipc/mojo/ipc_channel_mojo.cc

Issue 559723002: Refactoring: Move MessagePipeReader subclasess out from ChannelMojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Landing Created 6 years, 3 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 | « ipc/mojo/ipc_channel_mojo.h ('k') | ipc/mojo/ipc_channel_mojo_readers.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ipc/mojo/ipc_channel_mojo.cc
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc
index cdb928175dabcfda3104553ad88846b026b952b6..086b420cc52071ef90c7b53cf77249714efd67be 100644
--- a/ipc/mojo/ipc_channel_mojo.cc
+++ b/ipc/mojo/ipc_channel_mojo.cc
@@ -8,6 +8,7 @@
#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "ipc/ipc_listener.h"
+#include "ipc/mojo/ipc_channel_mojo_readers.h"
#include "mojo/embedder/embedder.h"
#if defined(OS_POSIX) && !defined(OS_NACL)
@@ -82,371 +83,10 @@ mojo::embedder::PlatformHandle ToPlatformHandle(
#endif
}
-//------------------------------------------------------------------------------
-
-// TODO(morrita): This should be built using higher-level Mojo construct
-// for clarity and extensibility.
-class HelloMessage {
- public:
- static Pickle CreateRequest(int32 pid) {
- Pickle request;
- request.WriteString(kHelloRequestMagic);
- request.WriteInt(pid);
- return request;
- }
-
- static bool ReadRequest(Pickle& pickle, int32* pid) {
- PickleIterator iter(pickle);
- std::string hello;
- if (!iter.ReadString(&hello)) {
- DLOG(WARNING) << "Failed to Read magic string.";
- return false;
- }
-
- if (hello != kHelloRequestMagic) {
- DLOG(WARNING) << "Magic mismatch:" << hello;
- return false;
- }
-
- int read_pid;
- if (!iter.ReadInt(&read_pid)) {
- DLOG(WARNING) << "Failed to Read PID.";
- return false;
- }
-
- *pid = read_pid;
- return true;
- }
-
- static Pickle CreateResponse(int32 pid) {
- Pickle request;
- request.WriteString(kHelloResponseMagic);
- request.WriteInt(pid);
- return request;
- }
-
- static bool ReadResponse(Pickle& pickle, int32* pid) {
- PickleIterator iter(pickle);
- std::string hello;
- if (!iter.ReadString(&hello)) {
- DLOG(WARNING) << "Failed to read magic string.";
- return false;
- }
-
- if (hello != kHelloResponseMagic) {
- DLOG(WARNING) << "Magic mismatch:" << hello;
- return false;
- }
-
- int read_pid;
- if (!iter.ReadInt(&read_pid)) {
- DLOG(WARNING) << "Failed to read PID.";
- return false;
- }
-
- *pid = read_pid;
- return true;
- }
-
- private:
- static const char* kHelloRequestMagic;
- static const char* kHelloResponseMagic;
-};
-
-const char* HelloMessage::kHelloRequestMagic = "MREQ";
-const char* HelloMessage::kHelloResponseMagic = "MRES";
-
} // namespace
//------------------------------------------------------------------------------
-// A MessagePipeReader implemenation for IPC::Message communication.
-class ChannelMojo::MessageReader : public internal::MessagePipeReader {
- public:
- MessageReader(mojo::ScopedMessagePipeHandle pipe, ChannelMojo* owner)
- : internal::MessagePipeReader(pipe.Pass()),
- owner_(owner) {}
-
- bool Send(scoped_ptr<Message> message);
- virtual void OnMessageReceived() OVERRIDE;
- virtual void OnPipeClosed() OVERRIDE;
- virtual void OnPipeError(MojoResult error) OVERRIDE;
-
- private:
- ChannelMojo* owner_;
-};
-
-void ChannelMojo::MessageReader::OnMessageReceived() {
- Message message(data_buffer().empty() ? "" : &data_buffer()[0],
- static_cast<uint32>(data_buffer().size()));
-
- std::vector<MojoHandle> handle_buffer;
- TakeHandleBuffer(&handle_buffer);
-#if defined(OS_POSIX) && !defined(OS_NACL)
- for (size_t i = 0; i < handle_buffer.size(); ++i) {
- mojo::embedder::ScopedPlatformHandle platform_handle;
- MojoResult unwrap_result = mojo::embedder::PassWrappedPlatformHandle(
- handle_buffer[i], &platform_handle);
- if (unwrap_result != MOJO_RESULT_OK) {
- DLOG(WARNING) << "Pipe failed to covert handles. Closing: "
- << unwrap_result;
- CloseWithError(unwrap_result);
- return;
- }
-
- bool ok = message.file_descriptor_set()->Add(platform_handle.release().fd);
- DCHECK(ok);
- }
-#else
- DCHECK(handle_buffer.empty());
-#endif
-
- message.TraceMessageEnd();
- owner_->OnMessageReceived(message);
-}
-
-void ChannelMojo::MessageReader::OnPipeClosed() {
- if (!owner_)
- return;
- owner_->OnPipeClosed(this);
- owner_ = NULL;
-}
-
-void ChannelMojo::MessageReader::OnPipeError(MojoResult error) {
- if (!owner_)
- return;
- owner_->OnPipeError(this);
-}
-
-bool ChannelMojo::MessageReader::Send(scoped_ptr<Message> message) {
- DCHECK(IsValid());
-
- message->TraceMessageBegin();
- std::vector<MojoHandle> handles;
-#if defined(OS_POSIX) && !defined(OS_NACL)
- // We dup() the handles in IPC::Message to transmit.
- // IPC::FileDescriptorSet has intricate lifecycle semantics
- // of FDs, so just to dup()-and-own them is the safest option.
- if (message->HasFileDescriptors()) {
- FileDescriptorSet* fdset = message->file_descriptor_set();
- for (size_t i = 0; i < fdset->size(); ++i) {
- int fd_to_send = dup(fdset->GetDescriptorAt(i));
- if (-1 == fd_to_send) {
- DPLOG(WARNING) << "Failed to dup FD to transmit.";
- std::for_each(handles.begin(), handles.end(), &MojoClose);
- CloseWithError(MOJO_RESULT_UNKNOWN);
- return false;
- }
-
- MojoHandle wrapped_handle;
- MojoResult wrap_result = CreatePlatformHandleWrapper(
- mojo::embedder::ScopedPlatformHandle(
- mojo::embedder::PlatformHandle(fd_to_send)),
- &wrapped_handle);
- if (MOJO_RESULT_OK != wrap_result) {
- DLOG(WARNING) << "Pipe failed to wrap handles. Closing: "
- << wrap_result;
- std::for_each(handles.begin(), handles.end(), &MojoClose);
- CloseWithError(wrap_result);
- return false;
- }
-
- handles.push_back(wrapped_handle);
- }
- }
-#endif
- MojoResult write_result = MojoWriteMessage(
- handle(),
- message->data(), static_cast<uint32>(message->size()),
- handles.empty() ? NULL : &handles[0],
- static_cast<uint32>(handles.size()),
- MOJO_WRITE_MESSAGE_FLAG_NONE);
- if (MOJO_RESULT_OK != write_result) {
- std::for_each(handles.begin(), handles.end(), &MojoClose);
- CloseWithError(write_result);
- return false;
- }
-
- return true;
-}
-
-//------------------------------------------------------------------------------
-
-// MessagePipeReader implementation for control messages.
-// Actual message handling is implemented by sublcasses.
-class ChannelMojo::ControlReader : public internal::MessagePipeReader {
- public:
- ControlReader(mojo::ScopedMessagePipeHandle pipe, ChannelMojo* owner)
- : internal::MessagePipeReader(pipe.Pass()),
- owner_(owner) {}
-
- virtual bool Connect() { return true; }
- virtual void OnPipeClosed() OVERRIDE;
- virtual void OnPipeError(MojoResult error) OVERRIDE;
-
- protected:
- ChannelMojo* owner_;
-};
-
-void ChannelMojo::ControlReader::OnPipeClosed() {
- if (!owner_)
- return;
- owner_->OnPipeClosed(this);
- owner_ = NULL;
-}
-
-void ChannelMojo::ControlReader::OnPipeError(MojoResult error) {
- if (!owner_)
- return;
- owner_->OnPipeError(this);
-}
-
-//------------------------------------------------------------------------------
-
-// ControlReader for server-side ChannelMojo.
-class ChannelMojo::ServerControlReader : public ChannelMojo::ControlReader {
- public:
- ServerControlReader(mojo::ScopedMessagePipeHandle pipe, ChannelMojo* owner)
- : ControlReader(pipe.Pass(), owner) { }
-
- virtual bool Connect() OVERRIDE;
- virtual void OnMessageReceived() OVERRIDE;
-
- private:
- MojoResult SendHelloRequest();
- MojoResult RespondHelloResponse();
-
- mojo::ScopedMessagePipeHandle message_pipe_;
-};
-
-bool ChannelMojo::ServerControlReader::Connect() {
- MojoResult result = SendHelloRequest();
- if (result != MOJO_RESULT_OK) {
- CloseWithError(result);
- return false;
- }
-
- return true;
-}
-
-MojoResult ChannelMojo::ServerControlReader::SendHelloRequest() {
- DCHECK(IsValid());
- DCHECK(!message_pipe_.is_valid());
-
- mojo::ScopedMessagePipeHandle self;
- mojo::ScopedMessagePipeHandle peer;
- MojoResult create_result = mojo::CreateMessagePipe(
- NULL, &message_pipe_, &peer);
- if (MOJO_RESULT_OK != create_result) {
- DLOG(WARNING) << "mojo::CreateMessagePipe failed: " << create_result;
- return create_result;
- }
-
- MojoHandle peer_to_send = peer.get().value();
- Pickle request = HelloMessage::CreateRequest(owner_->GetSelfPID());
- MojoResult write_result = MojoWriteMessage(
- handle(),
- request.data(), static_cast<uint32>(request.size()),
- &peer_to_send, 1,
- MOJO_WRITE_MESSAGE_FLAG_NONE);
- if (MOJO_RESULT_OK != write_result) {
- DLOG(WARNING) << "Writing Hello request failed: " << create_result;
- return write_result;
- }
-
- // |peer| is sent and no longer owned by |this|.
- (void)peer.release();
- return MOJO_RESULT_OK;
-}
-
-MojoResult ChannelMojo::ServerControlReader::RespondHelloResponse() {
- Pickle request(data_buffer().empty() ? "" : &data_buffer()[0],
- static_cast<uint32>(data_buffer().size()));
-
- int32 read_pid = 0;
- if (!HelloMessage::ReadResponse(request, &read_pid)) {
- DLOG(ERROR) << "Failed to parse Hello response.";
- return MOJO_RESULT_UNKNOWN;
- }
-
- base::ProcessId pid = static_cast<base::ProcessId>(read_pid);
- owner_->set_peer_pid(pid);
- owner_->OnConnected(message_pipe_.Pass());
- return MOJO_RESULT_OK;
-}
-
-void ChannelMojo::ServerControlReader::OnMessageReceived() {
- MojoResult result = RespondHelloResponse();
- if (result != MOJO_RESULT_OK)
- CloseWithError(result);
-}
-
-//------------------------------------------------------------------------------
-
-// ControlReader for client-side ChannelMojo.
-class ChannelMojo::ClientControlReader : public ChannelMojo::ControlReader {
- public:
- ClientControlReader(mojo::ScopedMessagePipeHandle pipe, ChannelMojo* owner)
- : ControlReader(pipe.Pass(), owner) {}
-
- virtual void OnMessageReceived() OVERRIDE;
-
- private:
- MojoResult RespondHelloRequest(MojoHandle message_channel);
-};
-
-MojoResult ChannelMojo::ClientControlReader::RespondHelloRequest(
- MojoHandle message_channel) {
- DCHECK(IsValid());
-
- mojo::ScopedMessagePipeHandle received_pipe(
- (mojo::MessagePipeHandle(message_channel)));
-
- int32 read_request = 0;
- Pickle request(data_buffer().empty() ? "" : &data_buffer()[0],
- static_cast<uint32>(data_buffer().size()));
- if (!HelloMessage::ReadRequest(request, &read_request)) {
- DLOG(ERROR) << "Hello request has wrong magic.";
- return MOJO_RESULT_UNKNOWN;
- }
-
- base::ProcessId pid = read_request;
- Pickle response = HelloMessage::CreateResponse(owner_->GetSelfPID());
- MojoResult write_result = MojoWriteMessage(
- handle(),
- response.data(), static_cast<uint32>(response.size()),
- NULL, 0,
- MOJO_WRITE_MESSAGE_FLAG_NONE);
- if (MOJO_RESULT_OK != write_result) {
- DLOG(ERROR) << "Writing Hello response failed: " << write_result;
- return write_result;
- }
-
- owner_->set_peer_pid(pid);
- owner_->OnConnected(received_pipe.Pass());
- return MOJO_RESULT_OK;
-}
-
-void ChannelMojo::ClientControlReader::OnMessageReceived() {
- std::vector<MojoHandle> handle_buffer;
- TakeHandleBuffer(&handle_buffer);
- if (handle_buffer.size() != 1) {
- DLOG(ERROR) << "Hello request doesn't contains required handle: "
- << handle_buffer.size();
- CloseWithError(MOJO_RESULT_UNKNOWN);
- return;
- }
-
- MojoResult result = RespondHelloRequest(handle_buffer[0]);
- if (result != MOJO_RESULT_OK) {
- DLOG(ERROR) << "Failed to respond Hello request. Closing: "
- << result;
- CloseWithError(result);
- }
-}
-
-//------------------------------------------------------------------------------
-
void ChannelMojo::ChannelInfoDeleter::operator()(
mojo::embedder::ChannelInfo* ptr) const {
mojo::embedder::DestroyChannelOnIOThread(ptr);
@@ -458,9 +98,8 @@ void ChannelMojo::ChannelInfoDeleter::operator()(
scoped_ptr<ChannelMojo> ChannelMojo::Create(
const ChannelHandle &channel_handle, Mode mode, Listener* listener,
scoped_refptr<base::TaskRunner> io_thread_task_runner) {
- return make_scoped_ptr(new ChannelMojo(
- Channel::Create(channel_handle, mode, g_null_listener.Pointer()),
- mode, listener, io_thread_task_runner));
+ return make_scoped_ptr(
+ new ChannelMojo(channel_handle, mode, listener, io_thread_task_runner));
}
// static
@@ -473,11 +112,14 @@ scoped_ptr<ChannelFactory> ChannelMojo::CreateFactory(
io_thread_task_runner)).PassAs<ChannelFactory>();
}
-ChannelMojo::ChannelMojo(
- scoped_ptr<Channel> bootstrap, Mode mode, Listener* listener,
- scoped_refptr<base::TaskRunner> io_thread_task_runner)
- : bootstrap_(bootstrap.Pass()),
- mode_(mode), listener_(listener),
+ChannelMojo::ChannelMojo(const ChannelHandle& channel_handle,
+ Mode mode,
+ Listener* listener,
+ scoped_refptr<base::TaskRunner> io_thread_task_runner)
+ : bootstrap_(
+ Channel::Create(channel_handle, mode, g_null_listener.Pointer())),
+ mode_(mode),
+ listener_(listener),
peer_pid_(base::kNullProcessId),
weak_factory_(this) {
if (base::MessageLoopProxy::current() == io_thread_task_runner.get()) {
@@ -504,10 +146,12 @@ void ChannelMojo::InitOnIOThread() {
switch (mode_) {
case MODE_SERVER:
- control_reader_.reset(new ServerControlReader(control_pipe.Pass(), this));
+ control_reader_.reset(
+ new internal::ServerControlReader(control_pipe.Pass(), this));
break;
case MODE_CLIENT:
- control_reader_.reset(new ClientControlReader(control_pipe.Pass(), this));
+ control_reader_.reset(
+ new internal::ClientControlReader(control_pipe.Pass(), this));
break;
default:
NOTREACHED();
@@ -527,7 +171,8 @@ void ChannelMojo::Close() {
}
void ChannelMojo::OnConnected(mojo::ScopedMessagePipeHandle pipe) {
- message_reader_ = make_scoped_ptr(new MessageReader(pipe.Pass(), this));
+ message_reader_ =
+ make_scoped_ptr(new internal::MessageReader(pipe.Pass(), this));
for (size_t i = 0; i < pending_messages_.size(); ++i) {
message_reader_->Send(make_scoped_ptr(pending_messages_[i]));
@@ -583,6 +228,62 @@ int ChannelMojo::GetClientFileDescriptor() const {
int ChannelMojo::TakeClientFileDescriptor() {
return bootstrap_->TakeClientFileDescriptor();
}
+
+// static
+MojoResult ChannelMojo::WriteToFileDescriptorSet(
+ const std::vector<MojoHandle>& handle_buffer,
+ Message* message) {
+ for (size_t i = 0; i < handle_buffer.size(); ++i) {
+ mojo::embedder::ScopedPlatformHandle platform_handle;
+ MojoResult unwrap_result = mojo::embedder::PassWrappedPlatformHandle(
+ handle_buffer[i], &platform_handle);
+ if (unwrap_result != MOJO_RESULT_OK) {
+ DLOG(WARNING) << "Pipe failed to covert handles. Closing: "
+ << unwrap_result;
+ return unwrap_result;
+ }
+
+ bool ok = message->file_descriptor_set()->Add(platform_handle.release().fd);
+ DCHECK(ok);
+ }
+
+ return MOJO_RESULT_OK;
+}
+
+// static
+MojoResult ChannelMojo::ReadFromFileDescriptorSet(
+ const Message& message,
+ std::vector<MojoHandle>* handles) {
+ // We dup() the handles in IPC::Message to transmit.
+ // IPC::FileDescriptorSet has intricate lifecycle semantics
+ // of FDs, so just to dup()-and-own them is the safest option.
+ if (message.HasFileDescriptors()) {
+ const FileDescriptorSet* fdset = message.file_descriptor_set();
+ for (size_t i = 0; i < fdset->size(); ++i) {
+ int fd_to_send = dup(fdset->GetDescriptorAt(i));
+ if (-1 == fd_to_send) {
+ DPLOG(WARNING) << "Failed to dup FD to transmit.";
+ return MOJO_RESULT_UNKNOWN;
+ }
+
+ MojoHandle wrapped_handle;
+ MojoResult wrap_result = CreatePlatformHandleWrapper(
+ mojo::embedder::ScopedPlatformHandle(
+ mojo::embedder::PlatformHandle(fd_to_send)),
+ &wrapped_handle);
+ if (MOJO_RESULT_OK != wrap_result) {
+ DLOG(WARNING) << "Pipe failed to wrap handles. Closing: "
+ << wrap_result;
+ return wrap_result;
+ }
+
+ handles->push_back(wrapped_handle);
+ }
+ }
+
+ return MOJO_RESULT_OK;
+}
+
#endif // defined(OS_POSIX) && !defined(OS_NACL)
} // namespace IPC
« no previous file with comments | « ipc/mojo/ipc_channel_mojo.h ('k') | ipc/mojo/ipc_channel_mojo_readers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698