| 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/embedder/embedder.h" | 5 #include "mojo/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 "mojo/embedder/platform_support.h" | 11 #include "mojo/embedder/platform_support.h" |
| 12 #include "mojo/system/channel.h" | 12 #include "mojo/system/channel.h" |
| 13 #include "mojo/system/channel_endpoint.h" | 13 #include "mojo/system/channel_endpoint.h" |
| 14 #include "mojo/system/core.h" | 14 #include "mojo/system/core.h" |
| 15 #include "mojo/system/entrypoints.h" | 15 #include "mojo/system/entrypoints.h" |
| 16 #include "mojo/system/message_in_transit.h" | 16 #include "mojo/system/message_in_transit.h" |
| 17 #include "mojo/system/message_pipe.h" | |
| 18 #include "mojo/system/message_pipe_dispatcher.h" | 17 #include "mojo/system/message_pipe_dispatcher.h" |
| 19 #include "mojo/system/platform_handle_dispatcher.h" | 18 #include "mojo/system/platform_handle_dispatcher.h" |
| 20 #include "mojo/system/raw_channel.h" | 19 #include "mojo/system/raw_channel.h" |
| 21 | 20 |
| 22 namespace mojo { | 21 namespace mojo { |
| 23 namespace embedder { | 22 namespace embedder { |
| 24 | 23 |
| 25 // This is defined here (instead of a header file), since it's opaque to the | 24 // This is defined here (instead of a header file), since it's opaque to the |
| 26 // outside world. But we need to define it before our (internal-only) functions | 25 // outside world. But we need to define it before our (internal-only) functions |
| 27 // that use it. | 26 // that use it. |
| 28 struct ChannelInfo { | 27 struct ChannelInfo { |
| 29 ChannelInfo() {} | 28 ChannelInfo() {} |
| 30 ~ChannelInfo() {} | 29 ~ChannelInfo() {} |
| 31 | 30 |
| 32 scoped_refptr<system::Channel> channel; | 31 scoped_refptr<system::Channel> channel; |
| 33 | 32 |
| 34 // May be null, in which case |DestroyChannelOnIOThread()| must be used (from | 33 // May be null, in which case |DestroyChannelOnIOThread()| must be used (from |
| 35 // the IO thread), instead of |DestroyChannel()|. | 34 // the IO thread), instead of |DestroyChannel()|. |
| 36 scoped_refptr<base::TaskRunner> io_thread_task_runner; | 35 scoped_refptr<base::TaskRunner> io_thread_task_runner; |
| 37 }; | 36 }; |
| 38 | 37 |
| 39 namespace { | 38 namespace { |
| 40 | 39 |
| 41 // Helper for |CreateChannel...()|. (Note: May return null for some failures.) | 40 // Helper for |CreateChannel...()|. (Note: May return null for some failures.) |
| 42 scoped_refptr<system::Channel> MakeChannel( | 41 scoped_refptr<system::Channel> MakeChannel( |
| 43 system::Core* core, | 42 system::Core* core, |
| 44 ScopedPlatformHandle platform_handle, | 43 ScopedPlatformHandle platform_handle, |
| 45 scoped_refptr<system::MessagePipe> message_pipe) { | 44 scoped_refptr<system::ChannelEndpoint> channel_endpoint) { |
| 46 DCHECK(platform_handle.is_valid()); | 45 DCHECK(platform_handle.is_valid()); |
| 47 | 46 |
| 48 // Create and initialize a |system::Channel|. | 47 // Create and initialize a |system::Channel|. |
| 49 scoped_refptr<system::Channel> channel = | 48 scoped_refptr<system::Channel> channel = |
| 50 new system::Channel(core->platform_support()); | 49 new system::Channel(core->platform_support()); |
| 51 if (!channel->Init(system::RawChannel::Create(platform_handle.Pass()))) { | 50 if (!channel->Init(system::RawChannel::Create(platform_handle.Pass()))) { |
| 52 // This is very unusual (e.g., maybe |platform_handle| was invalid or we | 51 // This is very unusual (e.g., maybe |platform_handle| was invalid or we |
| 53 // reached some system resource limit). | 52 // reached some system resource limit). |
| 54 LOG(ERROR) << "Channel::Init() failed"; | 53 LOG(ERROR) << "Channel::Init() failed"; |
| 55 // Return null, since |Shutdown()| shouldn't be called in this case. | 54 // Return null, since |Shutdown()| shouldn't be called in this case. |
| 56 return scoped_refptr<system::Channel>(); | 55 return scoped_refptr<system::Channel>(); |
| 57 } | 56 } |
| 58 // Once |Init()| has succeeded, we have to return |channel| (since | 57 // Once |Init()| has succeeded, we have to return |channel| (since |
| 59 // |Shutdown()| will have to be called on it). | 58 // |Shutdown()| will have to be called on it). |
| 60 | 59 |
| 61 // Attach the message pipe endpoint. | 60 // Attach the endpoint. |
| 62 system::MessageInTransit::EndpointId endpoint_id = channel->AttachEndpoint( | 61 system::MessageInTransit::EndpointId endpoint_id = |
| 63 make_scoped_refptr(new system::ChannelEndpoint(message_pipe.get(), 1))); | 62 channel->AttachEndpoint(channel_endpoint); |
| 64 if (endpoint_id == system::MessageInTransit::kInvalidEndpointId) { | 63 if (endpoint_id == system::MessageInTransit::kInvalidEndpointId) { |
| 65 // This means that, e.g., the other endpoint of the message pipe was closed | 64 // This means that, e.g., the other endpoint of the message pipe was closed |
| 66 // first. But it's not necessarily an error per se. | 65 // first. But it's not necessarily an error per se. |
| 67 DVLOG(2) << "Channel::AttachEndpoint() failed"; | 66 DVLOG(2) << "Channel::AttachEndpoint() failed"; |
| 68 return channel; | 67 return channel; |
| 69 } | 68 } |
| 70 CHECK_EQ(endpoint_id, system::Channel::kBootstrapEndpointId); | 69 CHECK_EQ(endpoint_id, system::Channel::kBootstrapEndpointId); |
| 71 | 70 |
| 72 if (!channel->RunMessagePipeEndpoint(system::Channel::kBootstrapEndpointId, | 71 if (!channel->RunMessagePipeEndpoint(system::Channel::kBootstrapEndpointId, |
| 73 system::Channel::kBootstrapEndpointId)) { | 72 system::Channel::kBootstrapEndpointId)) { |
| 74 // Currently, there's no reason for this to fail. | 73 // Currently, there's no reason for this to fail. |
| 75 NOTREACHED() << "Channel::RunMessagePipeEndpoint() failed"; | 74 NOTREACHED() << "Channel::RunMessagePipeEndpoint() failed"; |
| 76 return channel; | 75 return channel; |
| 77 } | 76 } |
| 78 | 77 |
| 79 return channel; | 78 return channel; |
| 80 } | 79 } |
| 81 | 80 |
| 82 void CreateChannelHelper( | 81 void CreateChannelHelper( |
| 83 system::Core* core, | 82 system::Core* core, |
| 84 ScopedPlatformHandle platform_handle, | 83 ScopedPlatformHandle platform_handle, |
| 85 scoped_ptr<ChannelInfo> channel_info, | 84 scoped_ptr<ChannelInfo> channel_info, |
| 86 scoped_refptr<system::MessagePipe> message_pipe, | 85 scoped_refptr<system::ChannelEndpoint> channel_endpoint, |
| 87 DidCreateChannelCallback callback, | 86 DidCreateChannelCallback callback, |
| 88 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { | 87 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { |
| 89 channel_info->channel = | 88 channel_info->channel = |
| 90 MakeChannel(core, platform_handle.Pass(), message_pipe); | 89 MakeChannel(core, platform_handle.Pass(), channel_endpoint); |
| 91 | 90 |
| 92 // Hand the channel back to the embedder. | 91 // Hand the channel back to the embedder. |
| 93 if (callback_thread_task_runner.get()) { | 92 if (callback_thread_task_runner.get()) { |
| 94 callback_thread_task_runner->PostTask( | 93 callback_thread_task_runner->PostTask( |
| 95 FROM_HERE, base::Bind(callback, channel_info.release())); | 94 FROM_HERE, base::Bind(callback, channel_info.release())); |
| 96 } else { | 95 } else { |
| 97 callback.Run(channel_info.release()); | 96 callback.Run(channel_info.release()); |
| 98 } | 97 } |
| 99 } | 98 } |
| 100 | 99 |
| 101 } // namespace | 100 } // namespace |
| 102 | 101 |
| 103 void Init(scoped_ptr<PlatformSupport> platform_support) { | 102 void Init(scoped_ptr<PlatformSupport> platform_support) { |
| 104 system::entrypoints::SetCore(new system::Core(platform_support.Pass())); | 103 system::entrypoints::SetCore(new system::Core(platform_support.Pass())); |
| 105 } | 104 } |
| 106 | 105 |
| 107 // TODO(vtl): Write tests for this. | 106 // TODO(vtl): Write tests for this. |
| 108 ScopedMessagePipeHandle CreateChannelOnIOThread( | 107 ScopedMessagePipeHandle CreateChannelOnIOThread( |
| 109 ScopedPlatformHandle platform_handle, | 108 ScopedPlatformHandle platform_handle, |
| 110 ChannelInfo** channel_info) { | 109 ChannelInfo** channel_info) { |
| 111 DCHECK(platform_handle.is_valid()); | 110 DCHECK(platform_handle.is_valid()); |
| 112 DCHECK(channel_info); | 111 DCHECK(channel_info); |
| 113 | 112 |
| 114 std::pair<scoped_refptr<system::MessagePipeDispatcher>, | 113 scoped_refptr<system::ChannelEndpoint> channel_endpoint; |
| 115 scoped_refptr<system::MessagePipe> > remote_message_pipe = | 114 scoped_refptr<system::MessagePipeDispatcher> dispatcher = |
| 116 system::MessagePipeDispatcher::CreateRemoteMessagePipe(); | 115 system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); |
| 117 | 116 |
| 118 system::Core* core = system::entrypoints::GetCore(); | 117 system::Core* core = system::entrypoints::GetCore(); |
| 119 DCHECK(core); | 118 DCHECK(core); |
| 120 ScopedMessagePipeHandle rv( | 119 ScopedMessagePipeHandle rv( |
| 121 MessagePipeHandle(core->AddDispatcher(remote_message_pipe.first))); | 120 MessagePipeHandle(core->AddDispatcher(dispatcher))); |
| 122 | 121 |
| 123 *channel_info = new ChannelInfo(); | 122 *channel_info = new ChannelInfo(); |
| 124 (*channel_info)->channel = | 123 (*channel_info)->channel = |
| 125 MakeChannel(core, platform_handle.Pass(), remote_message_pipe.second); | 124 MakeChannel(core, platform_handle.Pass(), channel_endpoint); |
| 126 | 125 |
| 127 return rv.Pass(); | 126 return rv.Pass(); |
| 128 } | 127 } |
| 129 | 128 |
| 130 ScopedMessagePipeHandle CreateChannel( | 129 ScopedMessagePipeHandle CreateChannel( |
| 131 ScopedPlatformHandle platform_handle, | 130 ScopedPlatformHandle platform_handle, |
| 132 scoped_refptr<base::TaskRunner> io_thread_task_runner, | 131 scoped_refptr<base::TaskRunner> io_thread_task_runner, |
| 133 DidCreateChannelCallback callback, | 132 DidCreateChannelCallback callback, |
| 134 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { | 133 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { |
| 135 DCHECK(platform_handle.is_valid()); | 134 DCHECK(platform_handle.is_valid()); |
| 136 | 135 |
| 137 std::pair<scoped_refptr<system::MessagePipeDispatcher>, | 136 scoped_refptr<system::ChannelEndpoint> channel_endpoint; |
| 138 scoped_refptr<system::MessagePipe> > remote_message_pipe = | 137 scoped_refptr<system::MessagePipeDispatcher> dispatcher = |
| 139 system::MessagePipeDispatcher::CreateRemoteMessagePipe(); | 138 system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); |
| 140 | 139 |
| 141 system::Core* core = system::entrypoints::GetCore(); | 140 system::Core* core = system::entrypoints::GetCore(); |
| 142 DCHECK(core); | 141 DCHECK(core); |
| 143 ScopedMessagePipeHandle rv( | 142 ScopedMessagePipeHandle rv( |
| 144 MessagePipeHandle(core->AddDispatcher(remote_message_pipe.first))); | 143 MessagePipeHandle(core->AddDispatcher(dispatcher))); |
| 145 | 144 |
| 146 scoped_ptr<ChannelInfo> channel_info(new ChannelInfo()); | 145 scoped_ptr<ChannelInfo> channel_info(new ChannelInfo()); |
| 147 channel_info->io_thread_task_runner = io_thread_task_runner; | 146 channel_info->io_thread_task_runner = io_thread_task_runner; |
| 148 | 147 |
| 149 if (rv.is_valid()) { | 148 if (rv.is_valid()) { |
| 150 io_thread_task_runner->PostTask(FROM_HERE, | 149 io_thread_task_runner->PostTask(FROM_HERE, |
| 151 base::Bind(&CreateChannelHelper, | 150 base::Bind(&CreateChannelHelper, |
| 152 base::Unretained(core), | 151 base::Unretained(core), |
| 153 base::Passed(&platform_handle), | 152 base::Passed(&platform_handle), |
| 154 base::Passed(&channel_info), | 153 base::Passed(&channel_info), |
| 155 remote_message_pipe.second, | 154 channel_endpoint, |
| 156 callback, | 155 callback, |
| 157 callback_thread_task_runner)); | 156 callback_thread_task_runner)); |
| 158 } else { | 157 } else { |
| 159 (callback_thread_task_runner.get() ? callback_thread_task_runner | 158 (callback_thread_task_runner.get() ? callback_thread_task_runner |
| 160 : io_thread_task_runner) | 159 : io_thread_task_runner) |
| 161 ->PostTask(FROM_HERE, base::Bind(callback, channel_info.release())); | 160 ->PostTask(FROM_HERE, base::Bind(callback, channel_info.release())); |
| 162 } | 161 } |
| 163 | 162 |
| 164 return rv.Pass(); | 163 return rv.Pass(); |
| 165 } | 164 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 | 231 |
| 233 *platform_handle = | 232 *platform_handle = |
| 234 static_cast<system::PlatformHandleDispatcher*>(dispatcher.get()) | 233 static_cast<system::PlatformHandleDispatcher*>(dispatcher.get()) |
| 235 ->PassPlatformHandle() | 234 ->PassPlatformHandle() |
| 236 .Pass(); | 235 .Pass(); |
| 237 return MOJO_RESULT_OK; | 236 return MOJO_RESULT_OK; |
| 238 } | 237 } |
| 239 | 238 |
| 240 } // namespace embedder | 239 } // namespace embedder |
| 241 } // namespace mojo | 240 } // namespace mojo |
| OLD | NEW |