OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "mojo/edk/embedder/embedder.h" |
| 6 |
| 7 #include "base/atomicops.h" |
| 8 #include "base/bind.h" |
| 9 #include "base/bind_helpers.h" |
| 10 #include "base/location.h" |
| 11 #include "base/logging.h" |
| 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/task_runner.h" |
| 14 #include "mojo/edk/embedder/embedder_internal.h" |
| 15 #include "mojo/edk/embedder/process_delegate.h" |
| 16 #include "mojo/edk/embedder/simple_platform_support.h" |
| 17 #include "mojo/edk/system/configuration.h" |
| 18 #include "mojo/edk/system/core.h" |
| 19 #include "mojo/edk/system/message_pipe_dispatcher.h" |
| 20 #include "mojo/edk/system/platform_handle_dispatcher.h" |
| 21 |
| 22 namespace mojo { |
| 23 namespace edk { |
| 24 |
| 25 // TODO(jam): move into annonymous namespace. Keep outside for debugging in VS |
| 26 // temporarily. |
| 27 int g_channel_count = 0; |
| 28 bool g_wait_for_no_more_channels = false; |
| 29 |
| 30 namespace { |
| 31 |
| 32 // Note: Called on the I/O thread. |
| 33 void ShutdownIPCSupportHelper(bool wait_for_no_more_channels) { |
| 34 if (wait_for_no_more_channels && g_channel_count) { |
| 35 g_wait_for_no_more_channels = true; |
| 36 return; |
| 37 } |
| 38 |
| 39 internal::g_delegate_thread_task_runner->PostTask( |
| 40 FROM_HERE, base::Bind(&ProcessDelegate::OnShutdownComplete, |
| 41 base::Unretained(internal::g_process_delegate))); |
| 42 } |
| 43 |
| 44 } // namespace |
| 45 |
| 46 namespace internal { |
| 47 |
| 48 // Declared in embedder_internal.h. |
| 49 PlatformSupport* g_platform_support = nullptr; |
| 50 Core* g_core = nullptr; |
| 51 |
| 52 base::TaskRunner* g_delegate_thread_task_runner; |
| 53 ProcessDelegate* g_process_delegate; |
| 54 base::TaskRunner* g_io_thread_task_runner = nullptr; |
| 55 |
| 56 void ChannelStarted() { |
| 57 DCHECK(g_io_thread_task_runner->RunsTasksOnCurrentThread()); |
| 58 g_channel_count++; |
| 59 } |
| 60 |
| 61 void ChannelShutdown() { |
| 62 DCHECK(g_io_thread_task_runner->RunsTasksOnCurrentThread()); |
| 63 g_channel_count--; |
| 64 if (!g_channel_count && g_wait_for_no_more_channels) { |
| 65 // Reset g_wait_for_no_more_channels for unit tests which initialize and |
| 66 // tear down multiple times in a process. |
| 67 g_wait_for_no_more_channels = false; |
| 68 ShutdownIPCSupportHelper(false); |
| 69 } |
| 70 } |
| 71 |
| 72 } // namespace internal |
| 73 |
| 74 void SetMaxMessageSize(size_t bytes) { |
| 75 GetMutableConfiguration()->max_message_num_bytes = bytes; |
| 76 } |
| 77 |
| 78 void Init() { |
| 79 DCHECK(!internal::g_platform_support); |
| 80 internal::g_platform_support = new SimplePlatformSupport(); |
| 81 |
| 82 DCHECK(!internal::g_core); |
| 83 internal::g_core = new Core(internal::g_platform_support); |
| 84 } |
| 85 |
| 86 MojoResult AsyncWait(MojoHandle handle, |
| 87 MojoHandleSignals signals, |
| 88 const base::Callback<void(MojoResult)>& callback) { |
| 89 return internal::g_core->AsyncWait(handle, signals, callback); |
| 90 } |
| 91 |
| 92 MojoResult CreatePlatformHandleWrapper( |
| 93 ScopedPlatformHandle platform_handle, |
| 94 MojoHandle* platform_handle_wrapper_handle) { |
| 95 DCHECK(platform_handle_wrapper_handle); |
| 96 |
| 97 scoped_refptr<Dispatcher> dispatcher = |
| 98 PlatformHandleDispatcher::Create(platform_handle.Pass()); |
| 99 |
| 100 DCHECK(internal::g_core); |
| 101 MojoHandle h = internal::g_core->AddDispatcher(dispatcher); |
| 102 if (h == MOJO_HANDLE_INVALID) { |
| 103 LOG(ERROR) << "Handle table full"; |
| 104 dispatcher->Close(); |
| 105 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 106 } |
| 107 |
| 108 *platform_handle_wrapper_handle = h; |
| 109 return MOJO_RESULT_OK; |
| 110 } |
| 111 |
| 112 MojoResult PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle, |
| 113 ScopedPlatformHandle* platform_handle) { |
| 114 DCHECK(platform_handle); |
| 115 |
| 116 DCHECK(internal::g_core); |
| 117 scoped_refptr<Dispatcher> dispatcher( |
| 118 internal::g_core->GetDispatcher(platform_handle_wrapper_handle)); |
| 119 if (!dispatcher) |
| 120 return MOJO_RESULT_INVALID_ARGUMENT; |
| 121 |
| 122 if (dispatcher->GetType() != Dispatcher::Type::PLATFORM_HANDLE) |
| 123 return MOJO_RESULT_INVALID_ARGUMENT; |
| 124 |
| 125 *platform_handle = |
| 126 static_cast<PlatformHandleDispatcher*>(dispatcher.get()) |
| 127 ->PassPlatformHandle() |
| 128 .Pass(); |
| 129 return MOJO_RESULT_OK; |
| 130 } |
| 131 |
| 132 void InitIPCSupport(scoped_refptr<base::TaskRunner> delegate_thread_task_runner, |
| 133 ProcessDelegate* process_delegate, |
| 134 scoped_refptr<base::TaskRunner> io_thread_task_runner) { |
| 135 // |Init()| must have already been called. |
| 136 DCHECK(internal::g_core); |
| 137 internal::g_delegate_thread_task_runner = delegate_thread_task_runner.get(); |
| 138 internal::g_process_delegate = process_delegate; |
| 139 internal::g_io_thread_task_runner = io_thread_task_runner.get(); |
| 140 } |
| 141 |
| 142 void ShutdownIPCSupportOnIOThread() { |
| 143 } |
| 144 |
| 145 void ShutdownIPCSupport() { |
| 146 internal::g_io_thread_task_runner->PostTask( |
| 147 FROM_HERE, base::Bind(&ShutdownIPCSupportHelper, false)); |
| 148 } |
| 149 |
| 150 void ShutdownIPCSupportAndWaitForNoChannels() { |
| 151 internal::g_io_thread_task_runner->PostTask( |
| 152 FROM_HERE, base::Bind(&ShutdownIPCSupportHelper, true)); |
| 153 } |
| 154 |
| 155 ScopedMessagePipeHandle CreateMessagePipe( |
| 156 ScopedPlatformHandle platform_handle) { |
| 157 scoped_refptr<MessagePipeDispatcher> dispatcher = |
| 158 MessagePipeDispatcher::Create( |
| 159 MessagePipeDispatcher::kDefaultCreateOptions); |
| 160 |
| 161 ScopedMessagePipeHandle rv( |
| 162 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); |
| 163 CHECK(rv.is_valid()); |
| 164 dispatcher->Init(platform_handle.Pass()); |
| 165 // TODO(vtl): The |.Pass()| below is only needed due to an MSVS bug; remove it |
| 166 // once that's fixed. |
| 167 return rv.Pass(); |
| 168 } |
| 169 |
| 170 } // namespace edk |
| 171 } // namespace mojo |
OLD | NEW |