Chromium Code Reviews| 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" | 12 #include "mojo/edk/embedder/embedder_internal.h" |
| 13 #include "mojo/edk/embedder/platform_support.h" | 13 #include "mojo/edk/embedder/platform_support.h" |
| 14 #include "mojo/edk/system/channel.h" | 14 #include "mojo/edk/system/channel.h" |
| 15 #include "mojo/edk/system/channel_endpoint.h" | 15 #include "mojo/edk/system/channel_endpoint.h" |
| 16 #include "mojo/edk/system/channel_info.h" | 16 #include "mojo/edk/system/channel_manager.h" |
| 17 #include "mojo/edk/system/configuration.h" | 17 #include "mojo/edk/system/configuration.h" |
| 18 #include "mojo/edk/system/core.h" | 18 #include "mojo/edk/system/core.h" |
| 19 #include "mojo/edk/system/message_pipe_dispatcher.h" | 19 #include "mojo/edk/system/message_pipe_dispatcher.h" |
| 20 #include "mojo/edk/system/platform_handle_dispatcher.h" | 20 #include "mojo/edk/system/platform_handle_dispatcher.h" |
| 21 #include "mojo/edk/system/raw_channel.h" | 21 #include "mojo/edk/system/raw_channel.h" |
| 22 | 22 |
| 23 namespace mojo { | 23 namespace mojo { |
| 24 namespace embedder { | 24 namespace embedder { |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 // Helper for |CreateChannel...()|. (Note: May return null for some failures.) | 28 // Helper for |CreateChannel...()|. Returns 0 on failure. Called on the channel |
| 29 scoped_refptr<system::Channel> MakeChannel( | 29 // creation thread. |
| 30 system::ChannelId MakeChannel( | |
| 30 ScopedPlatformHandle platform_handle, | 31 ScopedPlatformHandle platform_handle, |
| 31 scoped_refptr<system::ChannelEndpoint> channel_endpoint) { | 32 scoped_refptr<system::ChannelEndpoint> channel_endpoint) { |
| 32 DCHECK(platform_handle.is_valid()); | 33 DCHECK(platform_handle.is_valid()); |
| 33 | 34 |
| 34 // Create and initialize a |system::Channel|. | 35 // Create and initialize a |system::Channel|. |
| 36 DCHECK(internal::g_core); | |
| 35 scoped_refptr<system::Channel> channel = | 37 scoped_refptr<system::Channel> channel = |
| 36 new system::Channel(internal::g_core->platform_support()); | 38 new system::Channel(internal::g_core->platform_support()); |
| 37 if (!channel->Init(system::RawChannel::Create(platform_handle.Pass()))) { | 39 if (!channel->Init(system::RawChannel::Create(platform_handle.Pass()))) { |
| 38 // This is very unusual (e.g., maybe |platform_handle| was invalid or we | 40 // This is very unusual (e.g., maybe |platform_handle| was invalid or we |
| 39 // reached some system resource limit). | 41 // reached some system resource limit). |
| 40 LOG(ERROR) << "Channel::Init() failed"; | 42 LOG(ERROR) << "Channel::Init() failed"; |
| 41 // Return null, since |Shutdown()| shouldn't be called in this case. | 43 // Return null, since |Shutdown()| shouldn't be called in this case. |
| 42 return scoped_refptr<system::Channel>(); | 44 return 0; |
| 43 } | 45 } |
| 44 // Once |Init()| has succeeded, we have to return |channel| (since | |
| 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 |
| 49 DCHECK(internal::g_channel_manager); | |
| 50 return internal::g_channel_manager->AddChannel( | |
| 51 channel, base::MessageLoopProxy::current()); | |
| 49 } | 52 } |
| 50 | 53 |
| 54 // Helper for |CreateChannel()|. Called on the channel creation thread. | |
| 51 void CreateChannelHelper( | 55 void CreateChannelHelper( |
| 52 ScopedPlatformHandle platform_handle, | 56 ScopedPlatformHandle platform_handle, |
| 53 scoped_ptr<ChannelInfo> channel_info, | 57 scoped_ptr<ChannelInfo> channel_info, |
| 54 scoped_refptr<system::ChannelEndpoint> channel_endpoint, | 58 scoped_refptr<system::ChannelEndpoint> channel_endpoint, |
| 55 DidCreateChannelCallback callback, | 59 DidCreateChannelCallback callback, |
| 56 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { | 60 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { |
| 57 channel_info->channel = MakeChannel(platform_handle.Pass(), channel_endpoint); | 61 channel_info->channel_id = |
| 62 MakeChannel(platform_handle.Pass(), channel_endpoint); | |
| 58 | 63 |
| 59 // Hand the channel back to the embedder. | 64 // Hand the channel back to the embedder. |
| 60 if (callback_thread_task_runner.get()) { | 65 if (callback_thread_task_runner.get()) { |
| 61 callback_thread_task_runner->PostTask( | 66 callback_thread_task_runner->PostTask( |
| 62 FROM_HERE, base::Bind(callback, channel_info.release())); | 67 FROM_HERE, base::Bind(callback, channel_info.release())); |
| 63 } else { | 68 } else { |
| 64 callback.Run(channel_info.release()); | 69 callback.Run(channel_info.release()); |
| 65 } | 70 } |
| 66 } | 71 } |
| 67 | 72 |
| 68 } // namespace | 73 } // namespace |
| 69 | 74 |
| 70 namespace internal { | 75 namespace internal { |
| 71 | 76 |
| 72 // Declared in embedder_internal.h. | 77 // Declared in embedder_internal.h. |
| 73 system::Core* g_core = nullptr; | 78 system::Core* g_core = nullptr; |
| 79 system::ChannelManager* g_channel_manager = nullptr; | |
| 74 | 80 |
| 75 } // namespace internal | 81 } // namespace internal |
| 76 | 82 |
| 77 void Init(scoped_ptr<PlatformSupport> platform_support) { | 83 void Init(scoped_ptr<PlatformSupport> platform_support) { |
| 78 DCHECK(!internal::g_core); | 84 DCHECK(!internal::g_core); |
| 79 internal::g_core = new system::Core(platform_support.Pass()); | 85 internal::g_core = new system::Core(platform_support.Pass()); |
| 86 // TODO(vtl): Ditto. | |
|
yzshen1
2014/11/13 21:22:24
nit: It is not clear what this TODO means. (There
viettrungluu
2014/11/13 22:37:39
Oops, the DCHECK above got uncommented by a previo
| |
| 87 // DCHECK(!internal::g_channel_manager); | |
| 88 internal::g_channel_manager = new system::ChannelManager(); | |
| 80 } | 89 } |
| 81 | 90 |
| 82 Configuration* GetConfiguration() { | 91 Configuration* GetConfiguration() { |
| 83 return system::GetMutableConfiguration(); | 92 return system::GetMutableConfiguration(); |
| 84 } | 93 } |
| 85 | 94 |
| 86 // TODO(vtl): Write tests for this. | 95 // TODO(vtl): Write tests for this. |
| 87 ScopedMessagePipeHandle CreateChannelOnIOThread( | 96 ScopedMessagePipeHandle CreateChannelOnIOThread( |
| 88 ScopedPlatformHandle platform_handle, | 97 ScopedPlatformHandle platform_handle, |
| 89 ChannelInfo** channel_info) { | 98 ChannelInfo** channel_info) { |
| 90 DCHECK(platform_handle.is_valid()); | 99 DCHECK(platform_handle.is_valid()); |
| 91 DCHECK(channel_info); | 100 DCHECK(channel_info); |
| 92 | 101 |
| 93 scoped_refptr<system::ChannelEndpoint> channel_endpoint; | 102 scoped_refptr<system::ChannelEndpoint> channel_endpoint; |
| 94 scoped_refptr<system::MessagePipeDispatcher> dispatcher = | 103 scoped_refptr<system::MessagePipeDispatcher> dispatcher = |
| 95 system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); | 104 system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); |
| 96 | 105 |
| 97 DCHECK(internal::g_core); | 106 DCHECK(internal::g_core); |
| 98 ScopedMessagePipeHandle rv( | 107 ScopedMessagePipeHandle rv( |
| 99 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); | 108 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); |
| 100 | 109 |
| 101 *channel_info = | 110 *channel_info = |
| 102 new ChannelInfo(MakeChannel(platform_handle.Pass(), channel_endpoint), | 111 new ChannelInfo(MakeChannel(platform_handle.Pass(), channel_endpoint)); |
| 103 base::MessageLoopProxy::current()); | |
| 104 | 112 |
| 105 return rv.Pass(); | 113 return rv.Pass(); |
| 106 } | 114 } |
| 107 | 115 |
| 108 ScopedMessagePipeHandle CreateChannel( | 116 ScopedMessagePipeHandle CreateChannel( |
| 109 ScopedPlatformHandle platform_handle, | 117 ScopedPlatformHandle platform_handle, |
| 110 scoped_refptr<base::TaskRunner> io_thread_task_runner, | 118 scoped_refptr<base::TaskRunner> io_thread_task_runner, |
| 111 DidCreateChannelCallback callback, | 119 DidCreateChannelCallback callback, |
| 112 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { | 120 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { |
| 113 DCHECK(platform_handle.is_valid()); | 121 DCHECK(platform_handle.is_valid()); |
| 114 DCHECK(io_thread_task_runner.get()); | 122 DCHECK(io_thread_task_runner.get()); |
| 115 DCHECK(!callback.is_null()); | 123 DCHECK(!callback.is_null()); |
| 116 | 124 |
| 117 scoped_refptr<system::ChannelEndpoint> channel_endpoint; | 125 scoped_refptr<system::ChannelEndpoint> channel_endpoint; |
| 118 scoped_refptr<system::MessagePipeDispatcher> dispatcher = | 126 scoped_refptr<system::MessagePipeDispatcher> dispatcher = |
| 119 system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); | 127 system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); |
| 120 | 128 |
| 121 DCHECK(internal::g_core); | 129 DCHECK(internal::g_core); |
| 122 ScopedMessagePipeHandle rv( | 130 ScopedMessagePipeHandle rv( |
| 123 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); | 131 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); |
| 124 | 132 |
| 133 // We'll have to set |channel_info->channel_id| on the I/O thread. | |
| 125 scoped_ptr<ChannelInfo> channel_info(new ChannelInfo()); | 134 scoped_ptr<ChannelInfo> channel_info(new ChannelInfo()); |
| 126 // We'll have to set |channel_info->channel| on the I/O thread. | |
| 127 channel_info->channel_thread_task_runner = io_thread_task_runner; | |
| 128 | 135 |
| 129 if (rv.is_valid()) { | 136 if (rv.is_valid()) { |
| 130 io_thread_task_runner->PostTask( | 137 io_thread_task_runner->PostTask( |
| 131 FROM_HERE, | 138 FROM_HERE, |
| 132 base::Bind(&CreateChannelHelper, base::Passed(&platform_handle), | 139 base::Bind(&CreateChannelHelper, base::Passed(&platform_handle), |
| 133 base::Passed(&channel_info), channel_endpoint, callback, | 140 base::Passed(&channel_info), channel_endpoint, callback, |
| 134 callback_thread_task_runner)); | 141 callback_thread_task_runner)); |
| 135 } else { | 142 } else { |
| 136 (callback_thread_task_runner.get() ? callback_thread_task_runner | 143 (callback_thread_task_runner.get() ? callback_thread_task_runner |
| 137 : io_thread_task_runner) | 144 : io_thread_task_runner) |
| 138 ->PostTask(FROM_HERE, base::Bind(callback, channel_info.release())); | 145 ->PostTask(FROM_HERE, base::Bind(callback, channel_info.release())); |
| 139 } | 146 } |
| 140 | 147 |
| 141 return rv.Pass(); | 148 return rv.Pass(); |
| 142 } | 149 } |
| 143 | 150 |
| 144 void DestroyChannelOnIOThread(ChannelInfo* channel_info) { | 151 void DestroyChannelOnIOThread(ChannelInfo* channel_info) { |
|
yzshen1
2014/11/13 21:22:24
Does it make sense to remove this method?
viettrungluu
2014/11/13 22:37:39
Done.
| |
| 145 DCHECK(channel_info); | 152 // |ChannelManager::ShutdownChannel()| will destroy the channel synchronously |
| 146 if (!channel_info->channel.get()) { | 153 // if called on the channel thread. |
| 147 // Presumably, |Init()| on the channel failed. | 154 DestroyChannel(channel_info); |
| 148 return; | |
| 149 } | |
| 150 | |
| 151 channel_info->channel->Shutdown(); | |
| 152 delete channel_info; | |
| 153 } | 155 } |
| 154 | 156 |
| 155 // TODO(vtl): Write tests for this. | 157 // TODO(vtl): Write tests for this. |
| 156 void DestroyChannel(ChannelInfo* channel_info) { | 158 void DestroyChannel(ChannelInfo* channel_info) { |
| 157 DCHECK(channel_info); | 159 DCHECK(channel_info); |
| 158 DCHECK(channel_info->channel_thread_task_runner.get()); | 160 if (!channel_info->channel_id) { |
| 159 | |
| 160 if (!channel_info->channel.get()) { | |
| 161 // Presumably, |Init()| on the channel failed. | 161 // Presumably, |Init()| on the channel failed. |
| 162 return; | 162 return; |
| 163 } | 163 } |
| 164 | 164 |
| 165 channel_info->channel->WillShutdownSoon(); | 165 DCHECK(internal::g_channel_manager); |
| 166 channel_info->channel_thread_task_runner->PostTask( | 166 internal::g_channel_manager->ShutdownChannel(channel_info->channel_id); |
| 167 FROM_HERE, base::Bind(&DestroyChannelOnIOThread, channel_info)); | 167 delete channel_info; |
| 168 } | 168 } |
| 169 | 169 |
| 170 void WillDestroyChannelSoon(ChannelInfo* channel_info) { | 170 void WillDestroyChannelSoon(ChannelInfo* channel_info) { |
| 171 DCHECK(channel_info); | 171 DCHECK(channel_info); |
| 172 channel_info->channel->WillShutdownSoon(); | 172 DCHECK(internal::g_channel_manager); |
| 173 internal::g_channel_manager->WillShutdownChannel(channel_info->channel_id); | |
| 173 } | 174 } |
| 174 | 175 |
| 175 MojoResult CreatePlatformHandleWrapper( | 176 MojoResult CreatePlatformHandleWrapper( |
| 176 ScopedPlatformHandle platform_handle, | 177 ScopedPlatformHandle platform_handle, |
| 177 MojoHandle* platform_handle_wrapper_handle) { | 178 MojoHandle* platform_handle_wrapper_handle) { |
| 178 DCHECK(platform_handle_wrapper_handle); | 179 DCHECK(platform_handle_wrapper_handle); |
| 179 | 180 |
| 180 scoped_refptr<system::Dispatcher> dispatcher( | 181 scoped_refptr<system::Dispatcher> dispatcher( |
| 181 new system::PlatformHandleDispatcher(platform_handle.Pass())); | 182 new system::PlatformHandleDispatcher(platform_handle.Pass())); |
| 182 | 183 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 207 | 208 |
| 208 *platform_handle = | 209 *platform_handle = |
| 209 static_cast<system::PlatformHandleDispatcher*>(dispatcher.get()) | 210 static_cast<system::PlatformHandleDispatcher*>(dispatcher.get()) |
| 210 ->PassPlatformHandle() | 211 ->PassPlatformHandle() |
| 211 .Pass(); | 212 .Pass(); |
| 212 return MOJO_RESULT_OK; | 213 return MOJO_RESULT_OK; |
| 213 } | 214 } |
| 214 | 215 |
| 215 } // namespace embedder | 216 } // namespace embedder |
| 216 } // namespace mojo | 217 } // namespace mojo |
| OLD | NEW |