| Index: mojo/edk/system/child_broker_host.cc
|
| diff --git a/mojo/edk/system/child_broker_host.cc b/mojo/edk/system/child_broker_host.cc
|
| deleted file mode 100644
|
| index b85180087a69ee34a237ef496dffdfe04be00eb1..0000000000000000000000000000000000000000
|
| --- a/mojo/edk/system/child_broker_host.cc
|
| +++ /dev/null
|
| @@ -1,329 +0,0 @@
|
| -// Copyright 2015 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 "mojo/edk/system/child_broker_host.h"
|
| -
|
| -#include <stdint.h>
|
| -
|
| -#include <utility>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/lazy_instance.h"
|
| -#include "mojo/edk/embedder/embedder_internal.h"
|
| -#include "mojo/edk/embedder/platform_channel_pair.h"
|
| -#include "mojo/edk/system/broker_messages.h"
|
| -#include "mojo/edk/system/broker_state.h"
|
| -#include "mojo/edk/system/configuration.h"
|
| -#include "mojo/edk/system/core.h"
|
| -#include "mojo/edk/system/platform_handle_dispatcher.h"
|
| -
|
| -namespace mojo {
|
| -namespace edk {
|
| -
|
| -namespace {
|
| -#if defined(OS_WIN)
|
| -static const int kDefaultReadBufferSize = 256;
|
| -#endif
|
| -}
|
| -
|
| -ChildBrokerHost::ChildBrokerHost(base::ProcessHandle child_process,
|
| - ScopedPlatformHandle pipe)
|
| - : process_id_(base::GetProcId(child_process)), child_channel_(nullptr) {
|
| - ScopedPlatformHandle parent_async_channel_handle;
|
| -#if defined(OS_POSIX)
|
| - parent_async_channel_handle = std::move(pipe);
|
| -#else
|
| - DuplicateHandle(GetCurrentProcess(), child_process,
|
| - GetCurrentProcess(), &child_process,
|
| - 0, FALSE, DUPLICATE_SAME_ACCESS);
|
| - child_process_ = base::Process(child_process);
|
| - sync_channel_ = std::move(pipe);
|
| - memset(&read_context_.overlapped, 0, sizeof(read_context_.overlapped));
|
| - read_context_.handler = this;
|
| - memset(&write_context_.overlapped, 0, sizeof(write_context_.overlapped));
|
| - write_context_.handler = this;
|
| - read_data_.resize(kDefaultReadBufferSize);
|
| - num_bytes_read_ = 0;
|
| -
|
| - // See comment in ChildBroker::SetChildBrokerHostHandle. Summary is we need
|
| - // two pipes on Windows, so send the second one over the first one.
|
| - PlatformChannelPair parent_pipe;
|
| - parent_async_channel_handle = parent_pipe.PassServerHandle();
|
| -
|
| - HANDLE duplicated_child_handle =
|
| - DuplicateToChild(parent_pipe.PassClientHandle().release().handle);
|
| - BOOL rv = WriteFile(sync_channel_.get().handle,
|
| - &duplicated_child_handle, sizeof(duplicated_child_handle),
|
| - NULL, &write_context_.overlapped);
|
| - DCHECK(rv || GetLastError() == ERROR_IO_PENDING);
|
| -#endif
|
| -
|
| - internal::g_io_thread_task_runner->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&ChildBrokerHost::InitOnIO, base::Unretained(this),
|
| - base::Passed(&parent_async_channel_handle)));
|
| -}
|
| -
|
| -base::ProcessId ChildBrokerHost::GetProcessId() {
|
| - return process_id_;
|
| -}
|
| -
|
| -void ChildBrokerHost::ConnectToProcess(base::ProcessId process_id,
|
| - ScopedPlatformHandle pipe) {
|
| - if (!child_channel_)
|
| - return; // Can happen at process shutdown on Windows.
|
| - ConnectToProcessMessage data;
|
| - memset(&data, 0, sizeof(data));
|
| - data.type = CONNECT_TO_PROCESS;
|
| - data.process_id = process_id;
|
| - scoped_ptr<MessageInTransit> message(new MessageInTransit(
|
| - MessageInTransit::Type::MESSAGE, sizeof(data), &data));
|
| - scoped_refptr<Dispatcher> dispatcher =
|
| - PlatformHandleDispatcher::Create(std::move(pipe));
|
| - internal::g_core->AddDispatcher(dispatcher);
|
| - scoped_ptr<DispatcherVector> dispatchers(new DispatcherVector);
|
| - dispatchers->push_back(dispatcher);
|
| - message->SetDispatchers(std::move(dispatchers));
|
| - message->SerializeAndCloseDispatchers();
|
| - message->set_route_id(kBrokerRouteId);
|
| - child_channel_->channel()->WriteMessage(std::move(message));
|
| -}
|
| -
|
| -void ChildBrokerHost::ConnectMessagePipe(uint64_t pipe_id,
|
| - base::ProcessId process_id) {
|
| - if (!child_channel_)
|
| - return; // Can happen at process shutdown on Windows.
|
| - PeerPipeConnectedMessage data;
|
| - memset(&data, 0, sizeof(data));
|
| - data.type = PEER_PIPE_CONNECTED;
|
| - data.pipe_id = pipe_id;
|
| - data.process_id = process_id;
|
| - scoped_ptr<MessageInTransit> message(new MessageInTransit(
|
| - MessageInTransit::Type::MESSAGE, sizeof(data), &data));
|
| - message->set_route_id(kBrokerRouteId);
|
| - child_channel_->channel()->WriteMessage(std::move(message));
|
| -}
|
| -
|
| -void ChildBrokerHost::PeerDied(uint64_t pipe_id) {
|
| - if (!child_channel_)
|
| - return; // Can happen at process shutdown on Windows.
|
| - PeerDiedMessage data;
|
| - memset(&data, 0, sizeof(data));
|
| - data.type = PEER_DIED;
|
| - data.pipe_id = pipe_id;
|
| - scoped_ptr<MessageInTransit> message(new MessageInTransit(
|
| - MessageInTransit::Type::MESSAGE, sizeof(data), &data));
|
| - message->set_route_id(kBrokerRouteId);
|
| - child_channel_->channel()->WriteMessage(std::move(message));
|
| -}
|
| -
|
| -ChildBrokerHost::~ChildBrokerHost() {
|
| - DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
|
| - BrokerState::GetInstance()->ChildBrokerHostDestructed(this);
|
| - if (child_channel_)
|
| - child_channel_->RemoveRoute(kBrokerRouteId);
|
| -}
|
| -
|
| -void ChildBrokerHost::InitOnIO(
|
| - ScopedPlatformHandle parent_async_channel_handle) {
|
| - child_channel_ = new RoutedRawChannel(
|
| - std::move(parent_async_channel_handle),
|
| - base::Bind(&ChildBrokerHost::ChannelDestructed, base::Unretained(this)));
|
| - child_channel_->AddRoute(kBrokerRouteId, this);
|
| -
|
| - BrokerState::GetInstance()->ChildBrokerHostCreated(this);
|
| -
|
| -#if defined(OS_WIN)
|
| - // Call this after RoutedRawChannel calls its RawChannel::Init because this
|
| - // call could cause us to get notified that the child has gone away and to
|
| - // delete this class and shut down child_channel_ before Init() has run.
|
| - base::MessageLoopForIO::current()->RegisterIOHandler(
|
| - sync_channel_.get().handle, this);
|
| - BeginRead();
|
| -#endif
|
| -}
|
| -
|
| -void ChildBrokerHost::OnReadMessage(
|
| - const MessageInTransit::View& message_view,
|
| - ScopedPlatformHandleVectorPtr platform_handles) {
|
| - DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
|
| - CHECK(!platform_handles);
|
| - if (message_view.num_bytes() !=
|
| - static_cast<uint32_t>(sizeof(ConnectMessagePipeMessage))) {
|
| - NOTREACHED();
|
| - delete this;
|
| - }
|
| -
|
| - const ConnectMessagePipeMessage* message =
|
| - static_cast<const ConnectMessagePipeMessage*>(message_view.bytes());
|
| - switch(message->type) {
|
| - case CONNECT_MESSAGE_PIPE:
|
| - BrokerState::GetInstance()->HandleConnectMessagePipe(this,
|
| - message->pipe_id);
|
| - break;
|
| - case CANCEL_CONNECT_MESSAGE_PIPE:
|
| - BrokerState::GetInstance()->HandleCancelConnectMessagePipe(
|
| - message->pipe_id);
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - delete this;
|
| - }
|
| -}
|
| -
|
| -void ChildBrokerHost::OnError(Error error) {
|
| - DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
|
| - child_channel_->RemoveRoute(kBrokerRouteId);
|
| - child_channel_ = nullptr;
|
| -}
|
| -
|
| -void ChildBrokerHost::ChannelDestructed(RoutedRawChannel* channel) {
|
| - // On Windows, we have two pipes to the child process. It's easier to wait
|
| - // until we get the error from the pipe that is used for synchronous I/O.
|
| -#if !defined(OS_WIN)
|
| - delete this;
|
| -#endif
|
| -}
|
| -
|
| -#if defined(OS_WIN)
|
| -void ChildBrokerHost::BeginRead() {
|
| - BOOL rv = ReadFile(sync_channel_.get().handle,
|
| - &read_data_[num_bytes_read_],
|
| - static_cast<int>(read_data_.size() - num_bytes_read_),
|
| - nullptr, &read_context_.overlapped);
|
| - if (rv || GetLastError() == ERROR_IO_PENDING)
|
| - return;
|
| -
|
| - if (GetLastError() == ERROR_BROKEN_PIPE) {
|
| - delete this;
|
| - return;
|
| - }
|
| -
|
| - NOTREACHED() << "Unknown error in ChildBrokerHost " << rv;
|
| -}
|
| -
|
| -void ChildBrokerHost::OnIOCompleted(base::MessageLoopForIO::IOContext* context,
|
| - DWORD bytes_transferred,
|
| - DWORD error) {
|
| - DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
|
| - if (error == ERROR_BROKEN_PIPE) {
|
| - delete this;
|
| - return; // Child process exited or crashed.
|
| - }
|
| -
|
| - if (error != ERROR_SUCCESS) {
|
| - NOTREACHED() << "Error " << error << " in ChildBrokerHost.";
|
| - delete this;
|
| - return;
|
| - }
|
| -
|
| - if (context == &write_context_) {
|
| - write_data_.clear();
|
| - return;
|
| - }
|
| -
|
| - num_bytes_read_ += bytes_transferred;
|
| - CHECK_GE(num_bytes_read_, sizeof(uint32_t));
|
| - BrokerMessage* message = reinterpret_cast<BrokerMessage*>(&read_data_[0]);
|
| - if (num_bytes_read_ < message->size) {
|
| - read_data_.resize(message->size);
|
| - BeginRead();
|
| - return;
|
| - }
|
| -
|
| - // This should never fire because we only get new requests from a child
|
| - // process after it has read all the previous data we wrote.
|
| - if (!write_data_.empty()) {
|
| - NOTREACHED() << "ChildBrokerHost shouldn't have data to write when it gets "
|
| - << " a new request";
|
| - delete this;
|
| - return;
|
| - }
|
| -
|
| - if (message->id == CREATE_PLATFORM_CHANNEL_PAIR) {
|
| - PlatformChannelPair channel_pair;
|
| - uint32_t response_size = 2 * sizeof(HANDLE);
|
| - write_data_.resize(response_size);
|
| - HANDLE* handles = reinterpret_cast<HANDLE*>(&write_data_[0]);
|
| - handles[0] = DuplicateToChild(
|
| - channel_pair.PassServerHandle().release().handle);
|
| - handles[1] = DuplicateToChild(
|
| - channel_pair.PassClientHandle().release().handle);
|
| - } else if (message->id == HANDLE_TO_TOKEN) {
|
| - uint32_t count =
|
| - (message->size - kBrokerMessageHeaderSize) / sizeof(HANDLE);
|
| - if (count > GetConfiguration().max_message_num_handles) {
|
| - NOTREACHED() << "Too many handles from child process. Closing channel.";
|
| - delete this;
|
| - return;
|
| - }
|
| - uint32_t response_size = count * sizeof(uint64_t);
|
| - write_data_.resize(response_size);
|
| - uint64_t* tokens = reinterpret_cast<uint64_t*>(&write_data_[0]);
|
| - std::vector<PlatformHandle> duplicated_handles(count);
|
| - for (uint32_t i = 0; i < count; ++i) {
|
| - duplicated_handles[i] =
|
| - PlatformHandle(DuplicateFromChild(message->handles[i]));
|
| - }
|
| - BrokerState::GetInstance()->HandleToToken(
|
| - &duplicated_handles[0], count, tokens);
|
| - } else if (message->id == TOKEN_TO_HANDLE) {
|
| - uint32_t count =
|
| - (message->size - kBrokerMessageHeaderSize) / sizeof(uint64_t);
|
| - if (count > GetConfiguration().max_message_num_handles) {
|
| - NOTREACHED() << "Too many tokens from child process. Closing channel.";
|
| - delete this;
|
| - return;
|
| - }
|
| - uint32_t response_size = count * sizeof(HANDLE);
|
| - write_data_.resize(response_size);
|
| - HANDLE* handles = reinterpret_cast<HANDLE*>(&write_data_[0]);
|
| - std::vector<PlatformHandle> temp_handles(count);
|
| - BrokerState::GetInstance()->TokenToHandle(
|
| - &message->tokens[0], count, &temp_handles[0]);
|
| - for (uint32_t i = 0; i < count; ++i) {
|
| - if (temp_handles[i].is_valid()) {
|
| - handles[i] = DuplicateToChild(temp_handles[i].handle);
|
| - } else {
|
| - NOTREACHED() << "Unknown token";
|
| - handles[i] = INVALID_HANDLE_VALUE;
|
| - }
|
| - }
|
| - } else {
|
| - NOTREACHED() << "Unknown command. Stopping reading.";
|
| - delete this;
|
| - return;
|
| - }
|
| -
|
| - BOOL rv = WriteFile(sync_channel_.get().handle, &write_data_[0],
|
| - static_cast<int>(write_data_.size()), NULL,
|
| - &write_context_.overlapped);
|
| - DCHECK(rv || GetLastError() == ERROR_IO_PENDING);
|
| -
|
| - // Start reading again.
|
| - num_bytes_read_ = 0;
|
| - BeginRead();
|
| -}
|
| -
|
| -HANDLE ChildBrokerHost::DuplicateToChild(HANDLE handle) {
|
| - HANDLE rv = INVALID_HANDLE_VALUE;
|
| - BOOL result = DuplicateHandle(base::GetCurrentProcessHandle(), handle,
|
| - child_process_.Handle(), &rv, 0, FALSE,
|
| - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
|
| - DCHECK(result);
|
| - return rv;
|
| -}
|
| -
|
| -HANDLE ChildBrokerHost::DuplicateFromChild(HANDLE handle) {
|
| - HANDLE rv = INVALID_HANDLE_VALUE;
|
| - BOOL result = DuplicateHandle(child_process_.Handle(), handle,
|
| - base::GetCurrentProcessHandle(), &rv, 0, FALSE,
|
| - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
|
| - DCHECK(result);
|
| - return rv;
|
| -}
|
| -#endif
|
| -
|
| -} // namespace edk
|
| -} // namespace mojo
|
|
|