| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
| 12 #include "mojo/edk/embedder/embedder_internal.h" | |
| 13 #include "mojo/edk/embedder/platform_support.h" | 12 #include "mojo/edk/embedder/platform_support.h" |
| 14 #include "mojo/edk/system/channel.h" | 13 #include "mojo/edk/system/channel.h" |
| 15 #include "mojo/edk/system/channel_endpoint.h" | 14 #include "mojo/edk/system/channel_endpoint.h" |
| 16 #include "mojo/edk/system/channel_info.h" | 15 #include "mojo/edk/system/channel_info.h" |
| 17 #include "mojo/edk/system/configuration.h" | |
| 18 #include "mojo/edk/system/core.h" | 16 #include "mojo/edk/system/core.h" |
| 17 #include "mojo/edk/system/entrypoints.h" |
| 19 #include "mojo/edk/system/message_pipe_dispatcher.h" | 18 #include "mojo/edk/system/message_pipe_dispatcher.h" |
| 20 #include "mojo/edk/system/platform_handle_dispatcher.h" | 19 #include "mojo/edk/system/platform_handle_dispatcher.h" |
| 21 #include "mojo/edk/system/raw_channel.h" | 20 #include "mojo/edk/system/raw_channel.h" |
| 22 | 21 |
| 23 namespace mojo { | 22 namespace mojo { |
| 24 namespace embedder { | 23 namespace embedder { |
| 25 | 24 |
| 26 namespace { | 25 namespace { |
| 27 | 26 |
| 28 // Helper for |CreateChannel...()|. (Note: May return null for some failures.) | 27 // Helper for |CreateChannel...()|. (Note: May return null for some failures.) |
| 29 scoped_refptr<system::Channel> MakeChannel( | 28 scoped_refptr<system::Channel> MakeChannel( |
| 29 system::Core* core, |
| 30 ScopedPlatformHandle platform_handle, | 30 ScopedPlatformHandle platform_handle, |
| 31 scoped_refptr<system::ChannelEndpoint> channel_endpoint) { | 31 scoped_refptr<system::ChannelEndpoint> channel_endpoint) { |
| 32 DCHECK(platform_handle.is_valid()); | 32 DCHECK(platform_handle.is_valid()); |
| 33 | 33 |
| 34 // Create and initialize a |system::Channel|. | 34 // Create and initialize a |system::Channel|. |
| 35 scoped_refptr<system::Channel> channel = | 35 scoped_refptr<system::Channel> channel = |
| 36 new system::Channel(internal::g_core->platform_support()); | 36 new system::Channel(core->platform_support()); |
| 37 if (!channel->Init(system::RawChannel::Create(platform_handle.Pass()))) { | 37 if (!channel->Init(system::RawChannel::Create(platform_handle.Pass()))) { |
| 38 // This is very unusual (e.g., maybe |platform_handle| was invalid or we | 38 // This is very unusual (e.g., maybe |platform_handle| was invalid or we |
| 39 // reached some system resource limit). | 39 // reached some system resource limit). |
| 40 LOG(ERROR) << "Channel::Init() failed"; | 40 LOG(ERROR) << "Channel::Init() failed"; |
| 41 // Return null, since |Shutdown()| shouldn't be called in this case. | 41 // Return null, since |Shutdown()| shouldn't be called in this case. |
| 42 return scoped_refptr<system::Channel>(); | 42 return scoped_refptr<system::Channel>(); |
| 43 } | 43 } |
| 44 // Once |Init()| has succeeded, we have to return |channel| (since | 44 // Once |Init()| has succeeded, we have to return |channel| (since |
| 45 // |Shutdown()| will have to be called on it). | 45 // |Shutdown()| will have to be called on it). |
| 46 | 46 |
| 47 channel->AttachAndRunEndpoint(channel_endpoint, true); | 47 channel->AttachAndRunEndpoint(channel_endpoint, true); |
| 48 return channel; | 48 return channel; |
| 49 } | 49 } |
| 50 | 50 |
| 51 void CreateChannelHelper( | 51 void CreateChannelHelper( |
| 52 system::Core* core, |
| 52 ScopedPlatformHandle platform_handle, | 53 ScopedPlatformHandle platform_handle, |
| 53 scoped_ptr<ChannelInfo> channel_info, | 54 scoped_ptr<ChannelInfo> channel_info, |
| 54 scoped_refptr<system::ChannelEndpoint> channel_endpoint, | 55 scoped_refptr<system::ChannelEndpoint> channel_endpoint, |
| 55 DidCreateChannelCallback callback, | 56 DidCreateChannelCallback callback, |
| 56 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { | 57 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { |
| 57 channel_info->channel = MakeChannel(platform_handle.Pass(), channel_endpoint); | 58 channel_info->channel = |
| 59 MakeChannel(core, platform_handle.Pass(), channel_endpoint); |
| 58 | 60 |
| 59 // Hand the channel back to the embedder. | 61 // Hand the channel back to the embedder. |
| 60 if (callback_thread_task_runner.get()) { | 62 if (callback_thread_task_runner.get()) { |
| 61 callback_thread_task_runner->PostTask( | 63 callback_thread_task_runner->PostTask( |
| 62 FROM_HERE, base::Bind(callback, channel_info.release())); | 64 FROM_HERE, base::Bind(callback, channel_info.release())); |
| 63 } else { | 65 } else { |
| 64 callback.Run(channel_info.release()); | 66 callback.Run(channel_info.release()); |
| 65 } | 67 } |
| 66 } | 68 } |
| 67 | 69 |
| 68 } // namespace | 70 } // namespace |
| 69 | 71 |
| 70 namespace internal { | |
| 71 | |
| 72 // Declared in embedder_internal.h. | |
| 73 system::Core* g_core = nullptr; | |
| 74 | |
| 75 } // namespace internal | |
| 76 | |
| 77 void Init(scoped_ptr<PlatformSupport> platform_support) { | 72 void Init(scoped_ptr<PlatformSupport> platform_support) { |
| 78 // TODO(vtl): Uncomment after fixing Python bindings tests. crbug.com/432670 | 73 system::entrypoints::SetCore(new system::Core(platform_support.Pass())); |
| 79 // DCHECK(!internal::g_core); | |
| 80 internal::g_core = new system::Core(platform_support.Pass()); | |
| 81 } | |
| 82 | |
| 83 Configuration* GetConfiguration() { | |
| 84 return system::GetMutableConfiguration(); | |
| 85 } | 74 } |
| 86 | 75 |
| 87 // TODO(vtl): Write tests for this. | 76 // TODO(vtl): Write tests for this. |
| 88 ScopedMessagePipeHandle CreateChannelOnIOThread( | 77 ScopedMessagePipeHandle CreateChannelOnIOThread( |
| 89 ScopedPlatformHandle platform_handle, | 78 ScopedPlatformHandle platform_handle, |
| 90 ChannelInfo** channel_info) { | 79 ChannelInfo** channel_info) { |
| 91 DCHECK(platform_handle.is_valid()); | 80 DCHECK(platform_handle.is_valid()); |
| 92 DCHECK(channel_info); | 81 DCHECK(channel_info); |
| 93 | 82 |
| 94 scoped_refptr<system::ChannelEndpoint> channel_endpoint; | 83 scoped_refptr<system::ChannelEndpoint> channel_endpoint; |
| 95 scoped_refptr<system::MessagePipeDispatcher> dispatcher = | 84 scoped_refptr<system::MessagePipeDispatcher> dispatcher = |
| 96 system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); | 85 system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); |
| 97 | 86 |
| 98 DCHECK(internal::g_core); | 87 system::Core* core = system::entrypoints::GetCore(); |
| 88 DCHECK(core); |
| 99 ScopedMessagePipeHandle rv( | 89 ScopedMessagePipeHandle rv( |
| 100 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); | 90 MessagePipeHandle(core->AddDispatcher(dispatcher))); |
| 101 | 91 |
| 102 *channel_info = | 92 *channel_info = new ChannelInfo( |
| 103 new ChannelInfo(MakeChannel(platform_handle.Pass(), channel_endpoint), | 93 MakeChannel(core, platform_handle.Pass(), channel_endpoint), |
| 104 base::MessageLoopProxy::current()); | 94 base::MessageLoopProxy::current()); |
| 105 | 95 |
| 106 return rv.Pass(); | 96 return rv.Pass(); |
| 107 } | 97 } |
| 108 | 98 |
| 109 ScopedMessagePipeHandle CreateChannel( | 99 ScopedMessagePipeHandle CreateChannel( |
| 110 ScopedPlatformHandle platform_handle, | 100 ScopedPlatformHandle platform_handle, |
| 111 scoped_refptr<base::TaskRunner> io_thread_task_runner, | 101 scoped_refptr<base::TaskRunner> io_thread_task_runner, |
| 112 DidCreateChannelCallback callback, | 102 DidCreateChannelCallback callback, |
| 113 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { | 103 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { |
| 114 DCHECK(platform_handle.is_valid()); | 104 DCHECK(platform_handle.is_valid()); |
| 115 DCHECK(io_thread_task_runner.get()); | 105 DCHECK(io_thread_task_runner.get()); |
| 116 DCHECK(!callback.is_null()); | 106 DCHECK(!callback.is_null()); |
| 117 | 107 |
| 118 scoped_refptr<system::ChannelEndpoint> channel_endpoint; | 108 scoped_refptr<system::ChannelEndpoint> channel_endpoint; |
| 119 scoped_refptr<system::MessagePipeDispatcher> dispatcher = | 109 scoped_refptr<system::MessagePipeDispatcher> dispatcher = |
| 120 system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); | 110 system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); |
| 121 | 111 |
| 122 DCHECK(internal::g_core); | 112 system::Core* core = system::entrypoints::GetCore(); |
| 113 DCHECK(core); |
| 123 ScopedMessagePipeHandle rv( | 114 ScopedMessagePipeHandle rv( |
| 124 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); | 115 MessagePipeHandle(core->AddDispatcher(dispatcher))); |
| 125 | 116 |
| 126 scoped_ptr<ChannelInfo> channel_info(new ChannelInfo()); | 117 scoped_ptr<ChannelInfo> channel_info(new ChannelInfo()); |
| 127 // We'll have to set |channel_info->channel| on the I/O thread. | 118 // We'll have to set |channel_info->channel| on the I/O thread. |
| 128 channel_info->channel_thread_task_runner = io_thread_task_runner; | 119 channel_info->channel_thread_task_runner = io_thread_task_runner; |
| 129 | 120 |
| 130 if (rv.is_valid()) { | 121 if (rv.is_valid()) { |
| 131 io_thread_task_runner->PostTask( | 122 io_thread_task_runner->PostTask(FROM_HERE, |
| 132 FROM_HERE, | 123 base::Bind(&CreateChannelHelper, |
| 133 base::Bind(&CreateChannelHelper, base::Passed(&platform_handle), | 124 base::Unretained(core), |
| 134 base::Passed(&channel_info), channel_endpoint, callback, | 125 base::Passed(&platform_handle), |
| 135 callback_thread_task_runner)); | 126 base::Passed(&channel_info), |
| 127 channel_endpoint, |
| 128 callback, |
| 129 callback_thread_task_runner)); |
| 136 } else { | 130 } else { |
| 137 (callback_thread_task_runner.get() ? callback_thread_task_runner | 131 (callback_thread_task_runner.get() ? callback_thread_task_runner |
| 138 : io_thread_task_runner) | 132 : io_thread_task_runner) |
| 139 ->PostTask(FROM_HERE, base::Bind(callback, channel_info.release())); | 133 ->PostTask(FROM_HERE, base::Bind(callback, channel_info.release())); |
| 140 } | 134 } |
| 141 | 135 |
| 142 return rv.Pass(); | 136 return rv.Pass(); |
| 143 } | 137 } |
| 144 | 138 |
| 145 void DestroyChannelOnIOThread(ChannelInfo* channel_info) { | 139 void DestroyChannelOnIOThread(ChannelInfo* channel_info) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 174 } | 168 } |
| 175 | 169 |
| 176 MojoResult CreatePlatformHandleWrapper( | 170 MojoResult CreatePlatformHandleWrapper( |
| 177 ScopedPlatformHandle platform_handle, | 171 ScopedPlatformHandle platform_handle, |
| 178 MojoHandle* platform_handle_wrapper_handle) { | 172 MojoHandle* platform_handle_wrapper_handle) { |
| 179 DCHECK(platform_handle_wrapper_handle); | 173 DCHECK(platform_handle_wrapper_handle); |
| 180 | 174 |
| 181 scoped_refptr<system::Dispatcher> dispatcher( | 175 scoped_refptr<system::Dispatcher> dispatcher( |
| 182 new system::PlatformHandleDispatcher(platform_handle.Pass())); | 176 new system::PlatformHandleDispatcher(platform_handle.Pass())); |
| 183 | 177 |
| 184 DCHECK(internal::g_core); | 178 system::Core* core = system::entrypoints::GetCore(); |
| 185 MojoHandle h = internal::g_core->AddDispatcher(dispatcher); | 179 DCHECK(core); |
| 180 MojoHandle h = core->AddDispatcher(dispatcher); |
| 186 if (h == MOJO_HANDLE_INVALID) { | 181 if (h == MOJO_HANDLE_INVALID) { |
| 187 LOG(ERROR) << "Handle table full"; | 182 LOG(ERROR) << "Handle table full"; |
| 188 dispatcher->Close(); | 183 dispatcher->Close(); |
| 189 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 184 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 190 } | 185 } |
| 191 | 186 |
| 192 *platform_handle_wrapper_handle = h; | 187 *platform_handle_wrapper_handle = h; |
| 193 return MOJO_RESULT_OK; | 188 return MOJO_RESULT_OK; |
| 194 } | 189 } |
| 195 | 190 |
| 196 MojoResult PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle, | 191 MojoResult PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle, |
| 197 ScopedPlatformHandle* platform_handle) { | 192 ScopedPlatformHandle* platform_handle) { |
| 198 DCHECK(platform_handle); | 193 DCHECK(platform_handle); |
| 199 | 194 |
| 200 DCHECK(internal::g_core); | 195 system::Core* core = system::entrypoints::GetCore(); |
| 196 DCHECK(core); |
| 201 scoped_refptr<system::Dispatcher> dispatcher( | 197 scoped_refptr<system::Dispatcher> dispatcher( |
| 202 internal::g_core->GetDispatcher(platform_handle_wrapper_handle)); | 198 core->GetDispatcher(platform_handle_wrapper_handle)); |
| 203 if (!dispatcher.get()) | 199 if (!dispatcher.get()) |
| 204 return MOJO_RESULT_INVALID_ARGUMENT; | 200 return MOJO_RESULT_INVALID_ARGUMENT; |
| 205 | 201 |
| 206 if (dispatcher->GetType() != system::Dispatcher::kTypePlatformHandle) | 202 if (dispatcher->GetType() != system::Dispatcher::kTypePlatformHandle) |
| 207 return MOJO_RESULT_INVALID_ARGUMENT; | 203 return MOJO_RESULT_INVALID_ARGUMENT; |
| 208 | 204 |
| 209 *platform_handle = | 205 *platform_handle = |
| 210 static_cast<system::PlatformHandleDispatcher*>(dispatcher.get()) | 206 static_cast<system::PlatformHandleDispatcher*>(dispatcher.get()) |
| 211 ->PassPlatformHandle() | 207 ->PassPlatformHandle() |
| 212 .Pass(); | 208 .Pass(); |
| 213 return MOJO_RESULT_OK; | 209 return MOJO_RESULT_OK; |
| 214 } | 210 } |
| 215 | 211 |
| 216 } // namespace embedder | 212 } // namespace embedder |
| 217 } // namespace mojo | 213 } // namespace mojo |
| OLD | NEW |