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