| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/edk/embedder/embedder.h" | 5 #include "mojo/edk/embedder/embedder.h" |
| 6 | 6 |
| 7 #include <utility> | |
| 8 | |
| 9 #include "base/atomicops.h" | |
| 10 #include "base/logging.h" | 7 #include "base/logging.h" |
| 11 #include "mojo/edk/embedder/embedder_internal.h" | 8 #include "mojo/edk/embedder/embedder_internal.h" |
| 12 #include "mojo/edk/embedder/master_process_delegate.h" | 9 //#include "mojo/edk/embedder/platform_support.h" |
| 13 #include "mojo/edk/embedder/platform_support.h" | |
| 14 #include "mojo/edk/embedder/process_delegate.h" | |
| 15 #include "mojo/edk/embedder/slave_process_delegate.h" | |
| 16 #include "mojo/edk/system/channel.h" | |
| 17 #include "mojo/edk/system/channel_manager.h" | |
| 18 #include "mojo/edk/system/configuration.h" | 10 #include "mojo/edk/system/configuration.h" |
| 19 #include "mojo/edk/system/core.h" | 11 #include "mojo/edk/system/core.h" |
| 20 #include "mojo/edk/system/ipc_support.h" | |
| 21 #include "mojo/edk/system/message_pipe_dispatcher.h" | |
| 22 #include "mojo/edk/system/platform_handle_dispatcher.h" | 12 #include "mojo/edk/system/platform_handle_dispatcher.h" |
| 23 #include "mojo/edk/system/raw_channel.h" | |
| 24 #include "mojo/edk/util/ref_ptr.h" | |
| 25 | 13 |
| 26 using mojo::platform::PlatformHandleWatcher; | |
| 27 using mojo::platform::ScopedPlatformHandle; | 14 using mojo::platform::ScopedPlatformHandle; |
| 28 using mojo::platform::TaskRunner; | |
| 29 using mojo::util::RefPtr; | |
| 30 | 15 |
| 31 namespace mojo { | 16 namespace mojo { |
| 32 namespace embedder { | 17 namespace embedder { |
| 33 | 18 |
| 34 namespace internal { | 19 namespace internal { |
| 35 | 20 |
| 36 // Declared in embedder_internal.h. | 21 // Declared in embedder_internal.h. |
| 37 PlatformSupport* g_platform_support = nullptr; | 22 PlatformSupport* g_platform_support = nullptr; |
| 38 system::Core* g_core = nullptr; | 23 system::Core* g_core = nullptr; |
| 39 system::IPCSupport* g_ipc_support = nullptr; | |
| 40 | 24 |
| 41 } // namespace internal | 25 } // namespace internal |
| 42 | 26 |
| 43 namespace { | |
| 44 | |
| 45 // TODO(vtl): For now, we need this to be thread-safe (since theoretically we | |
| 46 // currently support multiple channel creation threads -- possibly one per | |
| 47 // channel). Eventually, we won't need it to be thread-safe (we'll require a | |
| 48 // single I/O thread), and eventually we won't need it at all. Remember to | |
| 49 // remove the base/atomicops.h include. | |
| 50 system::ChannelId MakeChannelId() { | |
| 51 // Note that |AtomicWord| is signed. | |
| 52 static base::subtle::AtomicWord counter = 0; | |
| 53 | |
| 54 base::subtle::AtomicWord new_counter_value = | |
| 55 base::subtle::NoBarrier_AtomicIncrement(&counter, 1); | |
| 56 // Don't allow the counter to wrap. Note that any (strictly) positive value is | |
| 57 // a valid |ChannelId| (and |NoBarrier_AtomicIncrement()| returns the value | |
| 58 // post-increment). | |
| 59 CHECK_GT(new_counter_value, 0); | |
| 60 // Use "negative" values for these IDs, so that we'll also be able to use | |
| 61 // "positive" "process identifiers" (see connection_manager.h) as IDs (and | |
| 62 // they won't conflict). | |
| 63 return static_cast<system::ChannelId>(-new_counter_value); | |
| 64 } | |
| 65 | |
| 66 } // namespace | |
| 67 | |
| 68 Configuration* GetConfiguration() { | 27 Configuration* GetConfiguration() { |
| 69 return system::GetMutableConfiguration(); | 28 return system::GetMutableConfiguration(); |
| 70 } | 29 } |
| 71 | 30 |
| 72 void Init(std::unique_ptr<PlatformSupport> platform_support) { | 31 void Init(std::unique_ptr<PlatformSupport> platform_support) { |
| 73 DCHECK(platform_support); | 32 DCHECK(platform_support); |
| 74 | 33 |
| 75 DCHECK(!internal::g_platform_support); | 34 DCHECK(!internal::g_platform_support); |
| 76 internal::g_platform_support = platform_support.release(); | 35 internal::g_platform_support = platform_support.release(); |
| 77 | 36 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 76 |
| 118 if (dispatcher->GetType() != system::Dispatcher::Type::PLATFORM_HANDLE) | 77 if (dispatcher->GetType() != system::Dispatcher::Type::PLATFORM_HANDLE) |
| 119 return MOJO_RESULT_INVALID_ARGUMENT; | 78 return MOJO_RESULT_INVALID_ARGUMENT; |
| 120 | 79 |
| 121 *platform_handle = | 80 *platform_handle = |
| 122 static_cast<system::PlatformHandleDispatcher*>(dispatcher.get()) | 81 static_cast<system::PlatformHandleDispatcher*>(dispatcher.get()) |
| 123 ->PassPlatformHandle(); | 82 ->PassPlatformHandle(); |
| 124 return MOJO_RESULT_OK; | 83 return MOJO_RESULT_OK; |
| 125 } | 84 } |
| 126 | 85 |
| 127 void InitIPCSupport(ProcessType process_type, | |
| 128 RefPtr<TaskRunner>&& delegate_thread_task_runner, | |
| 129 ProcessDelegate* process_delegate, | |
| 130 RefPtr<TaskRunner>&& io_task_runner, | |
| 131 PlatformHandleWatcher* io_watcher, | |
| 132 ScopedPlatformHandle platform_handle) { | |
| 133 // |Init()| must have already been called. | |
| 134 DCHECK(internal::g_core); | |
| 135 // And not |InitIPCSupport()| (without |ShutdownIPCSupport()|). | |
| 136 DCHECK(!internal::g_ipc_support); | |
| 137 | |
| 138 internal::g_ipc_support = new system::IPCSupport( | |
| 139 internal::g_platform_support, process_type, | |
| 140 std::move(delegate_thread_task_runner), process_delegate, | |
| 141 std::move(io_task_runner), io_watcher, platform_handle.Pass()); | |
| 142 } | |
| 143 | |
| 144 void ShutdownIPCSupportOnIOThread() { | |
| 145 DCHECK(internal::g_ipc_support); | |
| 146 | |
| 147 internal::g_ipc_support->ShutdownOnIOThread(); | |
| 148 delete internal::g_ipc_support; | |
| 149 internal::g_ipc_support = nullptr; | |
| 150 } | |
| 151 | |
| 152 void ShutdownIPCSupport() { | |
| 153 DCHECK(internal::g_ipc_support); | |
| 154 | |
| 155 internal::g_ipc_support->io_task_runner()->PostTask([]() { | |
| 156 // Save these before they get nuked by |ShutdownChannelOnIOThread()|. | |
| 157 RefPtr<TaskRunner> delegate_thread_task_runner( | |
| 158 internal::g_ipc_support->delegate_thread_task_runner()); | |
| 159 ProcessDelegate* process_delegate = | |
| 160 internal::g_ipc_support->process_delegate(); | |
| 161 | |
| 162 ShutdownIPCSupportOnIOThread(); | |
| 163 | |
| 164 delegate_thread_task_runner->PostTask( | |
| 165 [process_delegate]() { process_delegate->OnShutdownComplete(); }); | |
| 166 }); | |
| 167 } | |
| 168 | |
| 169 ScopedMessagePipeHandle ConnectToSlave( | |
| 170 SlaveInfo slave_info, | |
| 171 ScopedPlatformHandle platform_handle, | |
| 172 std::function<void()>&& did_connect_to_slave_callback, | |
| 173 RefPtr<TaskRunner>&& did_connect_to_slave_runner, | |
| 174 std::string* platform_connection_id, | |
| 175 ChannelInfo** channel_info) { | |
| 176 DCHECK(platform_connection_id); | |
| 177 DCHECK(channel_info); | |
| 178 DCHECK(internal::g_ipc_support); | |
| 179 | |
| 180 system::ConnectionIdentifier connection_id = | |
| 181 internal::g_ipc_support->GenerateConnectionIdentifier(); | |
| 182 *platform_connection_id = connection_id.ToString(); | |
| 183 system::ChannelId channel_id = system::kInvalidChannelId; | |
| 184 RefPtr<system::MessagePipeDispatcher> dispatcher = | |
| 185 internal::g_ipc_support->ConnectToSlave( | |
| 186 connection_id, slave_info, platform_handle.Pass(), | |
| 187 std::move(did_connect_to_slave_callback), | |
| 188 std::move(did_connect_to_slave_runner), &channel_id); | |
| 189 *channel_info = new ChannelInfo(channel_id); | |
| 190 | |
| 191 ScopedMessagePipeHandle rv( | |
| 192 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher.get()))); | |
| 193 CHECK(rv.is_valid()); | |
| 194 return rv; | |
| 195 } | |
| 196 | |
| 197 ScopedMessagePipeHandle ConnectToMaster( | |
| 198 const std::string& platform_connection_id, | |
| 199 std::function<void()>&& did_connect_to_master_callback, | |
| 200 RefPtr<TaskRunner>&& did_connect_to_master_runner, | |
| 201 ChannelInfo** channel_info) { | |
| 202 DCHECK(channel_info); | |
| 203 DCHECK(internal::g_ipc_support); | |
| 204 | |
| 205 bool ok = false; | |
| 206 system::ConnectionIdentifier connection_id = | |
| 207 system::ConnectionIdentifier::FromString(platform_connection_id, &ok); | |
| 208 CHECK(ok); | |
| 209 | |
| 210 system::ChannelId channel_id = system::kInvalidChannelId; | |
| 211 RefPtr<system::MessagePipeDispatcher> dispatcher = | |
| 212 internal::g_ipc_support->ConnectToMaster( | |
| 213 connection_id, std::move(did_connect_to_master_callback), | |
| 214 std::move(did_connect_to_master_runner), &channel_id); | |
| 215 *channel_info = new ChannelInfo(channel_id); | |
| 216 | |
| 217 ScopedMessagePipeHandle rv( | |
| 218 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher.get()))); | |
| 219 CHECK(rv.is_valid()); | |
| 220 return rv; | |
| 221 } | |
| 222 | |
| 223 // TODO(vtl): Write tests for this. | |
| 224 ScopedMessagePipeHandle CreateChannelOnIOThread( | |
| 225 ScopedPlatformHandle platform_handle, | |
| 226 ChannelInfo** channel_info) { | |
| 227 DCHECK(platform_handle.is_valid()); | |
| 228 DCHECK(channel_info); | |
| 229 DCHECK(internal::g_ipc_support); | |
| 230 | |
| 231 system::ChannelManager* channel_manager = | |
| 232 internal::g_ipc_support->channel_manager(); | |
| 233 | |
| 234 *channel_info = new ChannelInfo(MakeChannelId()); | |
| 235 RefPtr<system::MessagePipeDispatcher> dispatcher = | |
| 236 channel_manager->CreateChannelOnIOThread((*channel_info)->channel_id, | |
| 237 platform_handle.Pass()); | |
| 238 | |
| 239 ScopedMessagePipeHandle rv( | |
| 240 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher.get()))); | |
| 241 CHECK(rv.is_valid()); | |
| 242 return rv; | |
| 243 } | |
| 244 | |
| 245 ScopedMessagePipeHandle CreateChannel( | |
| 246 ScopedPlatformHandle platform_handle, | |
| 247 std::function<void(ChannelInfo*)>&& did_create_channel_callback, | |
| 248 RefPtr<TaskRunner>&& did_create_channel_runner) { | |
| 249 DCHECK(platform_handle.is_valid()); | |
| 250 DCHECK(did_create_channel_callback); | |
| 251 DCHECK(internal::g_ipc_support); | |
| 252 | |
| 253 system::ChannelManager* channel_manager = | |
| 254 internal::g_ipc_support->channel_manager(); | |
| 255 | |
| 256 system::ChannelId channel_id = MakeChannelId(); | |
| 257 // Ownership gets passed back to the caller via |did_create_channel_callback|. | |
| 258 ChannelInfo* channel_info = new ChannelInfo(channel_id); | |
| 259 RefPtr<system::MessagePipeDispatcher> dispatcher = | |
| 260 channel_manager->CreateChannel( | |
| 261 channel_id, platform_handle.Pass(), | |
| 262 [did_create_channel_callback, channel_info]() { | |
| 263 did_create_channel_callback(channel_info); | |
| 264 }, | |
| 265 std::move(did_create_channel_runner)); | |
| 266 | |
| 267 ScopedMessagePipeHandle rv( | |
| 268 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher.get()))); | |
| 269 CHECK(rv.is_valid()); | |
| 270 return rv; | |
| 271 } | |
| 272 | |
| 273 // TODO(vtl): Write tests for this. | |
| 274 void DestroyChannelOnIOThread(ChannelInfo* channel_info) { | |
| 275 DCHECK(channel_info); | |
| 276 DCHECK(channel_info->channel_id); | |
| 277 DCHECK(internal::g_ipc_support); | |
| 278 | |
| 279 system::ChannelManager* channel_manager = | |
| 280 internal::g_ipc_support->channel_manager(); | |
| 281 channel_manager->ShutdownChannelOnIOThread(channel_info->channel_id); | |
| 282 delete channel_info; | |
| 283 } | |
| 284 | |
| 285 // TODO(vtl): Write tests for this. | |
| 286 void DestroyChannel(ChannelInfo* channel_info, | |
| 287 std::function<void()>&& did_destroy_channel_callback, | |
| 288 RefPtr<TaskRunner>&& did_destroy_channel_runner) { | |
| 289 DCHECK(channel_info); | |
| 290 DCHECK(channel_info->channel_id); | |
| 291 DCHECK(did_destroy_channel_callback); | |
| 292 DCHECK(internal::g_ipc_support); | |
| 293 | |
| 294 system::ChannelManager* channel_manager = | |
| 295 internal::g_ipc_support->channel_manager(); | |
| 296 channel_manager->ShutdownChannel(channel_info->channel_id, | |
| 297 std::move(did_destroy_channel_callback), | |
| 298 std::move(did_destroy_channel_runner)); | |
| 299 delete channel_info; | |
| 300 } | |
| 301 | |
| 302 void WillDestroyChannelSoon(ChannelInfo* channel_info) { | |
| 303 DCHECK(channel_info); | |
| 304 DCHECK(internal::g_ipc_support); | |
| 305 | |
| 306 system::ChannelManager* channel_manager = | |
| 307 internal::g_ipc_support->channel_manager(); | |
| 308 channel_manager->WillShutdownChannel(channel_info->channel_id); | |
| 309 } | |
| 310 | |
| 311 } // namespace embedder | 86 } // namespace embedder |
| 312 } // namespace mojo | 87 } // namespace mojo |
| OLD | NEW |