| Index: mojo/edk/embedder/embedder.cc
|
| diff --git a/mojo/edk/embedder/embedder.cc b/mojo/edk/embedder/embedder.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9f2b94a974fc7eb5d7e06febca030d970a700491
|
| --- /dev/null
|
| +++ b/mojo/edk/embedder/embedder.cc
|
| @@ -0,0 +1,171 @@
|
| +// Copyright 2014 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/embedder/embedder.h"
|
| +
|
| +#include "base/atomicops.h"
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/location.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/task_runner.h"
|
| +#include "mojo/edk/embedder/embedder_internal.h"
|
| +#include "mojo/edk/embedder/process_delegate.h"
|
| +#include "mojo/edk/embedder/simple_platform_support.h"
|
| +#include "mojo/edk/system/configuration.h"
|
| +#include "mojo/edk/system/core.h"
|
| +#include "mojo/edk/system/message_pipe_dispatcher.h"
|
| +#include "mojo/edk/system/platform_handle_dispatcher.h"
|
| +
|
| +namespace mojo {
|
| +namespace edk {
|
| +
|
| +// TODO(jam): move into annonymous namespace. Keep outside for debugging in VS
|
| +// temporarily.
|
| +int g_channel_count = 0;
|
| +bool g_wait_for_no_more_channels = false;
|
| +
|
| +namespace {
|
| +
|
| +// Note: Called on the I/O thread.
|
| +void ShutdownIPCSupportHelper(bool wait_for_no_more_channels) {
|
| + if (wait_for_no_more_channels && g_channel_count) {
|
| + g_wait_for_no_more_channels = true;
|
| + return;
|
| + }
|
| +
|
| + internal::g_delegate_thread_task_runner->PostTask(
|
| + FROM_HERE, base::Bind(&ProcessDelegate::OnShutdownComplete,
|
| + base::Unretained(internal::g_process_delegate)));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace internal {
|
| +
|
| +// Declared in embedder_internal.h.
|
| +PlatformSupport* g_platform_support = nullptr;
|
| +Core* g_core = nullptr;
|
| +
|
| +base::TaskRunner* g_delegate_thread_task_runner;
|
| +ProcessDelegate* g_process_delegate;
|
| +base::TaskRunner* g_io_thread_task_runner = nullptr;
|
| +
|
| +void ChannelStarted() {
|
| + DCHECK(g_io_thread_task_runner->RunsTasksOnCurrentThread());
|
| + g_channel_count++;
|
| +}
|
| +
|
| +void ChannelShutdown() {
|
| + DCHECK(g_io_thread_task_runner->RunsTasksOnCurrentThread());
|
| + g_channel_count--;
|
| + if (!g_channel_count && g_wait_for_no_more_channels) {
|
| + // Reset g_wait_for_no_more_channels for unit tests which initialize and
|
| + // tear down multiple times in a process.
|
| + g_wait_for_no_more_channels = false;
|
| + ShutdownIPCSupportHelper(false);
|
| + }
|
| +}
|
| +
|
| +} // namespace internal
|
| +
|
| +void SetMaxMessageSize(size_t bytes) {
|
| + GetMutableConfiguration()->max_message_num_bytes = bytes;
|
| +}
|
| +
|
| +void Init() {
|
| + DCHECK(!internal::g_platform_support);
|
| + internal::g_platform_support = new SimplePlatformSupport();
|
| +
|
| + DCHECK(!internal::g_core);
|
| + internal::g_core = new Core(internal::g_platform_support);
|
| +}
|
| +
|
| +MojoResult AsyncWait(MojoHandle handle,
|
| + MojoHandleSignals signals,
|
| + const base::Callback<void(MojoResult)>& callback) {
|
| + return internal::g_core->AsyncWait(handle, signals, callback);
|
| +}
|
| +
|
| +MojoResult CreatePlatformHandleWrapper(
|
| + ScopedPlatformHandle platform_handle,
|
| + MojoHandle* platform_handle_wrapper_handle) {
|
| + DCHECK(platform_handle_wrapper_handle);
|
| +
|
| + scoped_refptr<Dispatcher> dispatcher =
|
| + PlatformHandleDispatcher::Create(platform_handle.Pass());
|
| +
|
| + DCHECK(internal::g_core);
|
| + MojoHandle h = internal::g_core->AddDispatcher(dispatcher);
|
| + if (h == MOJO_HANDLE_INVALID) {
|
| + LOG(ERROR) << "Handle table full";
|
| + dispatcher->Close();
|
| + return MOJO_RESULT_RESOURCE_EXHAUSTED;
|
| + }
|
| +
|
| + *platform_handle_wrapper_handle = h;
|
| + return MOJO_RESULT_OK;
|
| +}
|
| +
|
| +MojoResult PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle,
|
| + ScopedPlatformHandle* platform_handle) {
|
| + DCHECK(platform_handle);
|
| +
|
| + DCHECK(internal::g_core);
|
| + scoped_refptr<Dispatcher> dispatcher(
|
| + internal::g_core->GetDispatcher(platform_handle_wrapper_handle));
|
| + if (!dispatcher)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| +
|
| + if (dispatcher->GetType() != Dispatcher::Type::PLATFORM_HANDLE)
|
| + return MOJO_RESULT_INVALID_ARGUMENT;
|
| +
|
| + *platform_handle =
|
| + static_cast<PlatformHandleDispatcher*>(dispatcher.get())
|
| + ->PassPlatformHandle()
|
| + .Pass();
|
| + return MOJO_RESULT_OK;
|
| +}
|
| +
|
| +void InitIPCSupport(scoped_refptr<base::TaskRunner> delegate_thread_task_runner,
|
| + ProcessDelegate* process_delegate,
|
| + scoped_refptr<base::TaskRunner> io_thread_task_runner) {
|
| + // |Init()| must have already been called.
|
| + DCHECK(internal::g_core);
|
| + internal::g_delegate_thread_task_runner = delegate_thread_task_runner.get();
|
| + internal::g_process_delegate = process_delegate;
|
| + internal::g_io_thread_task_runner = io_thread_task_runner.get();
|
| +}
|
| +
|
| +void ShutdownIPCSupportOnIOThread() {
|
| +}
|
| +
|
| +void ShutdownIPCSupport() {
|
| + internal::g_io_thread_task_runner->PostTask(
|
| + FROM_HERE, base::Bind(&ShutdownIPCSupportHelper, false));
|
| +}
|
| +
|
| +void ShutdownIPCSupportAndWaitForNoChannels() {
|
| + internal::g_io_thread_task_runner->PostTask(
|
| + FROM_HERE, base::Bind(&ShutdownIPCSupportHelper, true));
|
| +}
|
| +
|
| +ScopedMessagePipeHandle CreateMessagePipe(
|
| + ScopedPlatformHandle platform_handle) {
|
| + scoped_refptr<MessagePipeDispatcher> dispatcher =
|
| + MessagePipeDispatcher::Create(
|
| + MessagePipeDispatcher::kDefaultCreateOptions);
|
| +
|
| + ScopedMessagePipeHandle rv(
|
| + MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher)));
|
| + CHECK(rv.is_valid());
|
| + dispatcher->Init(platform_handle.Pass());
|
| + // TODO(vtl): The |.Pass()| below is only needed due to an MSVS bug; remove it
|
| + // once that's fixed.
|
| + return rv.Pass();
|
| +}
|
| +
|
| +} // namespace edk
|
| +} // namespace mojo
|
|
|