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 |