OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/system/dispatcher.h" | 5 #include "mojo/edk/system/dispatcher.h" |
6 | 6 |
7 #include <stddef.h> | |
8 #include <stdint.h> | |
9 | |
10 #include "base/logging.h" | 7 #include "base/logging.h" |
11 #include "mojo/edk/system/configuration.h" | 8 #include "mojo/edk/system/configuration.h" |
12 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" | 9 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" |
13 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" | 10 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" |
14 #include "mojo/edk/system/message_pipe_dispatcher.h" | 11 #include "mojo/edk/system/message_pipe_dispatcher.h" |
15 #include "mojo/edk/system/platform_handle_dispatcher.h" | 12 #include "mojo/edk/system/platform_handle_dispatcher.h" |
16 #include "mojo/edk/system/shared_buffer_dispatcher.h" | 13 #include "mojo/edk/system/shared_buffer_dispatcher.h" |
17 | 14 |
18 namespace mojo { | 15 namespace mojo { |
19 namespace edk { | 16 namespace edk { |
20 | 17 |
21 namespace test { | 18 Dispatcher::DispatcherInTransit::DispatcherInTransit() {} |
22 | 19 |
23 // TODO(vtl): Maybe this should be defined in a test-only file instead. | 20 Dispatcher::DispatcherInTransit::~DispatcherInTransit() {} |
24 DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher) { | |
25 return Dispatcher::HandleTableAccess::TryStartTransport(dispatcher); | |
26 } | |
27 | 21 |
28 } // namespace test | 22 MojoResult Dispatcher::WriteMessage(const void* bytes, |
29 | 23 uint32_t num_bytes, |
30 // Dispatcher ------------------------------------------------------------------ | 24 const DispatcherInTransit* dispatchers, |
31 | 25 uint32_t num_dispatchers, |
32 // static | 26 MojoWriteMessageFlags flags) { |
33 DispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport( | 27 return MOJO_RESULT_INVALID_ARGUMENT; |
34 Dispatcher* dispatcher) { | |
35 DCHECK(dispatcher); | |
36 | |
37 // Our dispatcher implementations hop to IO thread on initialization, so it's | |
38 // valid that while their RawChannel os being initialized on IO thread, the | |
39 // dispatcher is being sent. We handle this by just acquiring the lock. | |
40 | |
41 // See comment in header for why we need this. | |
42 dispatcher->TransportStarted(); | |
43 | |
44 dispatcher->lock_.Acquire(); | |
45 | |
46 // We shouldn't race with things that close dispatchers, since closing can | |
47 // only take place either under |handle_table_lock_| or when the handle is | |
48 // marked as busy. | |
49 DCHECK(!dispatcher->is_closed_); | |
50 | |
51 return DispatcherTransport(dispatcher); | |
52 } | |
53 | |
54 // static | |
55 void Dispatcher::TransportDataAccess::StartSerialize( | |
56 Dispatcher* dispatcher, | |
57 size_t* max_size, | |
58 size_t* max_platform_handles) { | |
59 DCHECK(dispatcher); | |
60 dispatcher->StartSerialize(max_size, max_platform_handles); | |
61 } | |
62 | |
63 // static | |
64 bool Dispatcher::TransportDataAccess::EndSerializeAndClose( | |
65 Dispatcher* dispatcher, | |
66 void* destination, | |
67 size_t* actual_size, | |
68 PlatformHandleVector* platform_handles) { | |
69 DCHECK(dispatcher); | |
70 return dispatcher->EndSerializeAndClose(destination, actual_size, | |
71 platform_handles); | |
72 } | |
73 | |
74 // static | |
75 scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize( | |
76 int32_t type, | |
77 const void* source, | |
78 size_t size, | |
79 PlatformHandleVector* platform_handles) { | |
80 switch (static_cast<Dispatcher::Type>(type)) { | |
81 case Type::UNKNOWN: | |
82 case Type::WAIT_SET: | |
83 DVLOG(2) << "Deserializing invalid handle"; | |
84 return nullptr; | |
85 case Type::MESSAGE_PIPE: | |
86 return scoped_refptr<Dispatcher>(MessagePipeDispatcher::Deserialize( | |
87 source, size, platform_handles)); | |
88 case Type::DATA_PIPE_PRODUCER: | |
89 return scoped_refptr<Dispatcher>( | |
90 DataPipeProducerDispatcher::Deserialize( | |
91 source, size, platform_handles)); | |
92 case Type::DATA_PIPE_CONSUMER: | |
93 return scoped_refptr<Dispatcher>( | |
94 DataPipeConsumerDispatcher::Deserialize( | |
95 source, size, platform_handles)); | |
96 case Type::SHARED_BUFFER: | |
97 return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize( | |
98 source, size, platform_handles)); | |
99 case Type::PLATFORM_HANDLE: | |
100 return scoped_refptr<Dispatcher>(PlatformHandleDispatcher::Deserialize( | |
101 source, size, platform_handles)); | |
102 } | |
103 LOG(WARNING) << "Unknown dispatcher type " << type; | |
104 return nullptr; | |
105 } | |
106 | |
107 MojoResult Dispatcher::Close() { | |
108 base::AutoLock locker(lock_); | |
109 if (is_closed_) | |
110 return MOJO_RESULT_INVALID_ARGUMENT; | |
111 | |
112 CloseNoLock(); | |
113 return MOJO_RESULT_OK; | |
114 } | |
115 | |
116 MojoResult Dispatcher::WriteMessage( | |
117 const void* bytes, | |
118 uint32_t num_bytes, | |
119 std::vector<DispatcherTransport>* transports, | |
120 MojoWriteMessageFlags flags) { | |
121 DCHECK(!transports || | |
122 (transports->size() > 0 && | |
123 transports->size() < GetConfiguration().max_message_num_handles)); | |
124 | |
125 base::AutoLock locker(lock_); | |
126 if (is_closed_) | |
127 return MOJO_RESULT_INVALID_ARGUMENT; | |
128 | |
129 return WriteMessageImplNoLock(bytes, num_bytes, transports, flags); | |
130 } | 28 } |
131 | 29 |
132 MojoResult Dispatcher::ReadMessage(void* bytes, | 30 MojoResult Dispatcher::ReadMessage(void* bytes, |
133 uint32_t* num_bytes, | 31 uint32_t* num_bytes, |
134 DispatcherVector* dispatchers, | 32 MojoHandle* handles, |
135 uint32_t* num_dispatchers, | 33 uint32_t* num_handles, |
136 MojoReadMessageFlags flags) { | 34 MojoReadMessageFlags flags) { |
137 DCHECK(!num_dispatchers || *num_dispatchers == 0 || | 35 return MOJO_RESULT_INVALID_ARGUMENT; |
138 (dispatchers && dispatchers->empty())); | |
139 | |
140 base::AutoLock locker(lock_); | |
141 if (is_closed_) | |
142 return MOJO_RESULT_INVALID_ARGUMENT; | |
143 | |
144 return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers, | |
145 flags); | |
146 } | |
147 | |
148 MojoResult Dispatcher::WriteData(const void* elements, | |
149 uint32_t* num_bytes, | |
150 MojoWriteDataFlags flags) { | |
151 base::AutoLock locker(lock_); | |
152 if (is_closed_) | |
153 return MOJO_RESULT_INVALID_ARGUMENT; | |
154 | |
155 return WriteDataImplNoLock(elements, num_bytes, flags); | |
156 } | |
157 | |
158 MojoResult Dispatcher::BeginWriteData(void** buffer, | |
159 uint32_t* buffer_num_bytes, | |
160 MojoWriteDataFlags flags) { | |
161 base::AutoLock locker(lock_); | |
162 if (is_closed_) | |
163 return MOJO_RESULT_INVALID_ARGUMENT; | |
164 | |
165 return BeginWriteDataImplNoLock(buffer, buffer_num_bytes, flags); | |
166 } | |
167 | |
168 MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) { | |
169 base::AutoLock locker(lock_); | |
170 if (is_closed_) | |
171 return MOJO_RESULT_INVALID_ARGUMENT; | |
172 | |
173 return EndWriteDataImplNoLock(num_bytes_written); | |
174 } | |
175 | |
176 MojoResult Dispatcher::ReadData(void* elements, | |
177 uint32_t* num_bytes, | |
178 MojoReadDataFlags flags) { | |
179 base::AutoLock locker(lock_); | |
180 if (is_closed_) | |
181 return MOJO_RESULT_INVALID_ARGUMENT; | |
182 | |
183 return ReadDataImplNoLock(elements, num_bytes, flags); | |
184 } | |
185 | |
186 MojoResult Dispatcher::BeginReadData(const void** buffer, | |
187 uint32_t* buffer_num_bytes, | |
188 MojoReadDataFlags flags) { | |
189 base::AutoLock locker(lock_); | |
190 if (is_closed_) | |
191 return MOJO_RESULT_INVALID_ARGUMENT; | |
192 | |
193 return BeginReadDataImplNoLock(buffer, buffer_num_bytes, flags); | |
194 } | |
195 | |
196 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { | |
197 base::AutoLock locker(lock_); | |
198 if (is_closed_) | |
199 return MOJO_RESULT_INVALID_ARGUMENT; | |
200 | |
201 return EndReadDataImplNoLock(num_bytes_read); | |
202 } | 36 } |
203 | 37 |
204 MojoResult Dispatcher::DuplicateBufferHandle( | 38 MojoResult Dispatcher::DuplicateBufferHandle( |
205 const MojoDuplicateBufferHandleOptions* options, | 39 const MojoDuplicateBufferHandleOptions* options, |
206 scoped_refptr<Dispatcher>* new_dispatcher) { | 40 scoped_refptr<Dispatcher>* new_dispatcher) { |
207 base::AutoLock locker(lock_); | 41 return MOJO_RESULT_INVALID_ARGUMENT; |
208 if (is_closed_) | |
209 return MOJO_RESULT_INVALID_ARGUMENT; | |
210 | |
211 return DuplicateBufferHandleImplNoLock(options, new_dispatcher); | |
212 } | 42 } |
213 | 43 |
214 MojoResult Dispatcher::MapBuffer( | 44 MojoResult Dispatcher::MapBuffer( |
215 uint64_t offset, | 45 uint64_t offset, |
216 uint64_t num_bytes, | 46 uint64_t num_bytes, |
217 MojoMapBufferFlags flags, | 47 MojoMapBufferFlags flags, |
218 scoped_ptr<PlatformSharedBufferMapping>* mapping) { | 48 scoped_ptr<PlatformSharedBufferMapping>* mapping) { |
219 base::AutoLock locker(lock_); | 49 return MOJO_RESULT_INVALID_ARGUMENT; |
220 if (is_closed_) | 50 } |
221 return MOJO_RESULT_INVALID_ARGUMENT; | |
222 | 51 |
223 return MapBufferImplNoLock(offset, num_bytes, flags, mapping); | 52 MojoResult Dispatcher::ReadData(void* elements, |
| 53 uint32_t* num_bytes, |
| 54 MojoReadDataFlags flags) { |
| 55 return MOJO_RESULT_INVALID_ARGUMENT; |
| 56 } |
| 57 |
| 58 MojoResult Dispatcher::BeginReadData(const void** buffer, |
| 59 uint32_t* buffer_num_bytes, |
| 60 MojoReadDataFlags flags) { |
| 61 return MOJO_RESULT_INVALID_ARGUMENT; |
| 62 } |
| 63 |
| 64 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { |
| 65 return MOJO_RESULT_INVALID_ARGUMENT; |
| 66 } |
| 67 |
| 68 MojoResult Dispatcher::WriteData(const void* elements, |
| 69 uint32_t* num_bytes, |
| 70 MojoWriteDataFlags flags) { |
| 71 return MOJO_RESULT_INVALID_ARGUMENT; |
| 72 } |
| 73 |
| 74 MojoResult Dispatcher::BeginWriteData(void** buffer, |
| 75 uint32_t* buffer_num_bytes, |
| 76 MojoWriteDataFlags flags) { |
| 77 return MOJO_RESULT_INVALID_ARGUMENT; |
| 78 } |
| 79 |
| 80 MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) { |
| 81 return MOJO_RESULT_INVALID_ARGUMENT; |
| 82 } |
| 83 |
| 84 MojoResult Dispatcher::AddWaitingDispatcher( |
| 85 const scoped_refptr<Dispatcher>& dispatcher, |
| 86 MojoHandleSignals signals, |
| 87 uintptr_t context) { |
| 88 return MOJO_RESULT_INVALID_ARGUMENT; |
| 89 } |
| 90 |
| 91 MojoResult Dispatcher::RemoveWaitingDispatcher( |
| 92 const scoped_refptr<Dispatcher>& dispatcher) { |
| 93 return MOJO_RESULT_INVALID_ARGUMENT; |
| 94 } |
| 95 |
| 96 MojoResult Dispatcher::GetReadyDispatchers(uint32_t* count, |
| 97 DispatcherVector* dispatchers, |
| 98 MojoResult* results, |
| 99 uintptr_t* contexts) { |
| 100 return MOJO_RESULT_INVALID_ARGUMENT; |
224 } | 101 } |
225 | 102 |
226 HandleSignalsState Dispatcher::GetHandleSignalsState() const { | 103 HandleSignalsState Dispatcher::GetHandleSignalsState() const { |
227 base::AutoLock locker(lock_); | 104 return HandleSignalsState(); |
228 if (is_closed_) | |
229 return HandleSignalsState(); | |
230 | |
231 return GetHandleSignalsStateImplNoLock(); | |
232 } | 105 } |
233 | 106 |
234 MojoResult Dispatcher::AddAwakable(Awakable* awakable, | 107 MojoResult Dispatcher::AddAwakable(Awakable* awakable, |
235 MojoHandleSignals signals, | 108 MojoHandleSignals signals, |
236 uintptr_t context, | 109 uintptr_t context, |
237 HandleSignalsState* signals_state) { | 110 HandleSignalsState* signals_state) { |
238 base::AutoLock locker(lock_); | 111 return MOJO_RESULT_INVALID_ARGUMENT; |
239 if (is_closed_) { | |
240 if (signals_state) | |
241 *signals_state = HandleSignalsState(); | |
242 return MOJO_RESULT_INVALID_ARGUMENT; | |
243 } | |
244 | |
245 return AddAwakableImplNoLock(awakable, signals, context, signals_state); | |
246 } | 112 } |
247 | 113 |
248 void Dispatcher::RemoveAwakable(Awakable* awakable, | 114 void Dispatcher::RemoveAwakable(Awakable* awakable, |
249 HandleSignalsState* handle_signals_state) { | 115 HandleSignalsState* handle_signals_state) { |
250 base::AutoLock locker(lock_); | 116 NOTREACHED(); |
251 if (is_closed_) { | |
252 if (handle_signals_state) | |
253 *handle_signals_state = HandleSignalsState(); | |
254 return; | |
255 } | |
256 | |
257 RemoveAwakableImplNoLock(awakable, handle_signals_state); | |
258 } | 117 } |
259 | 118 |
260 MojoResult Dispatcher::AddWaitingDispatcher( | 119 void Dispatcher::StartSerialize(uint32_t* num_bytes, |
261 const scoped_refptr<Dispatcher>& dispatcher, | 120 uint32_t* num_ports, |
262 MojoHandleSignals signals, | 121 uint32_t* num_platform_handles) { |
263 uintptr_t context) { | 122 *num_bytes = 0; |
264 base::AutoLock locker(lock_); | 123 *num_ports = 0; |
265 if (is_closed_) | 124 *num_platform_handles = 0; |
266 return MOJO_RESULT_INVALID_ARGUMENT; | |
267 | |
268 return AddWaitingDispatcherImplNoLock(dispatcher, signals, context); | |
269 } | 125 } |
270 | 126 |
271 MojoResult Dispatcher::RemoveWaitingDispatcher( | 127 bool Dispatcher::EndSerialize(void* destination, |
272 const scoped_refptr<Dispatcher>& dispatcher) { | 128 ports::PortName* ports, |
273 base::AutoLock locker(lock_); | 129 PlatformHandle* handles) { |
274 if (is_closed_) | 130 LOG(ERROR) << "Attempting to serialize a non-transferrable dispatcher."; |
275 return MOJO_RESULT_INVALID_ARGUMENT; | 131 return true; |
276 | |
277 return RemoveWaitingDispatcherImplNoLock(dispatcher); | |
278 } | 132 } |
279 | 133 |
280 MojoResult Dispatcher::GetReadyDispatchers(uint32_t* count, | 134 bool Dispatcher::BeginTransit() { return true; } |
281 DispatcherVector* dispatchers, | |
282 MojoResult* results, | |
283 uintptr_t* contexts) { | |
284 base::AutoLock locker(lock_); | |
285 if (is_closed_) | |
286 return MOJO_RESULT_INVALID_ARGUMENT; | |
287 | 135 |
288 return GetReadyDispatchersImplNoLock(count, dispatchers, results, contexts); | 136 void Dispatcher::CompleteTransitAndClose() {} |
| 137 |
| 138 void Dispatcher::CancelTransit() {} |
| 139 |
| 140 // static |
| 141 scoped_refptr<Dispatcher> Dispatcher::Deserialize( |
| 142 Type type, |
| 143 const void* bytes, |
| 144 size_t num_bytes, |
| 145 const ports::PortName* ports, |
| 146 size_t num_ports, |
| 147 PlatformHandle* platform_handles, |
| 148 size_t num_platform_handles) { |
| 149 switch (type) { |
| 150 case Type::MESSAGE_PIPE: |
| 151 return MessagePipeDispatcher::Deserialize( |
| 152 bytes, num_bytes, ports, num_ports, platform_handles, |
| 153 num_platform_handles); |
| 154 case Type::SHARED_BUFFER: |
| 155 return SharedBufferDispatcher::Deserialize( |
| 156 bytes, num_bytes, ports, num_ports, platform_handles, |
| 157 num_platform_handles); |
| 158 case Type::DATA_PIPE_CONSUMER: |
| 159 return DataPipeConsumerDispatcher::Deserialize( |
| 160 bytes, num_bytes, ports, num_ports, platform_handles, |
| 161 num_platform_handles); |
| 162 case Type::DATA_PIPE_PRODUCER: |
| 163 return DataPipeProducerDispatcher::Deserialize( |
| 164 bytes, num_bytes, ports, num_ports, platform_handles, |
| 165 num_platform_handles); |
| 166 case Type::PLATFORM_HANDLE: |
| 167 return PlatformHandleDispatcher::Deserialize( |
| 168 bytes, num_bytes, ports, num_ports, platform_handles, |
| 169 num_platform_handles); |
| 170 default: |
| 171 LOG(ERROR) << "Deserializing invalid dispatcher type."; |
| 172 return nullptr; |
| 173 } |
289 } | 174 } |
290 | 175 |
291 Dispatcher::Dispatcher() : is_closed_(false) { | 176 Dispatcher::Dispatcher() {} |
292 } | |
293 | 177 |
294 Dispatcher::~Dispatcher() { | 178 Dispatcher::~Dispatcher() {} |
295 // Make sure that |Close()| was called. | |
296 DCHECK(is_closed_); | |
297 } | |
298 | |
299 void Dispatcher::CancelAllAwakablesNoLock() { | |
300 lock_.AssertAcquired(); | |
301 DCHECK(is_closed_); | |
302 // By default, waiting isn't supported. Only dispatchers that can be waited on | |
303 // will do something nontrivial. | |
304 } | |
305 | |
306 void Dispatcher::CloseImplNoLock() { | |
307 lock_.AssertAcquired(); | |
308 DCHECK(is_closed_); | |
309 // This may not need to do anything. Dispatchers should override this to do | |
310 // any actual close-time cleanup necessary. | |
311 } | |
312 | |
313 MojoResult Dispatcher::WriteMessageImplNoLock( | |
314 const void* /*bytes*/, | |
315 uint32_t /*num_bytes*/, | |
316 std::vector<DispatcherTransport>* /*transports*/, | |
317 MojoWriteMessageFlags /*flags*/) { | |
318 lock_.AssertAcquired(); | |
319 DCHECK(!is_closed_); | |
320 // By default, not supported. Only needed for message pipe dispatchers. | |
321 return MOJO_RESULT_INVALID_ARGUMENT; | |
322 } | |
323 | |
324 MojoResult Dispatcher::ReadMessageImplNoLock( | |
325 void* /*bytes*/, | |
326 uint32_t* /*num_bytes*/, | |
327 DispatcherVector* /*dispatchers*/, | |
328 uint32_t* /*num_dispatchers*/, | |
329 MojoReadMessageFlags /*flags*/) { | |
330 lock_.AssertAcquired(); | |
331 DCHECK(!is_closed_); | |
332 // By default, not supported. Only needed for message pipe dispatchers. | |
333 return MOJO_RESULT_INVALID_ARGUMENT; | |
334 } | |
335 | |
336 MojoResult Dispatcher::WriteDataImplNoLock(const void* /*elements*/, | |
337 uint32_t* /*num_bytes*/, | |
338 MojoWriteDataFlags /*flags*/) { | |
339 lock_.AssertAcquired(); | |
340 DCHECK(!is_closed_); | |
341 // By default, not supported. Only needed for data pipe dispatchers. | |
342 return MOJO_RESULT_INVALID_ARGUMENT; | |
343 } | |
344 | |
345 MojoResult Dispatcher::BeginWriteDataImplNoLock( | |
346 void** /*buffer*/, | |
347 uint32_t* /*buffer_num_bytes*/, | |
348 MojoWriteDataFlags /*flags*/) { | |
349 lock_.AssertAcquired(); | |
350 DCHECK(!is_closed_); | |
351 // By default, not supported. Only needed for data pipe dispatchers. | |
352 return MOJO_RESULT_INVALID_ARGUMENT; | |
353 } | |
354 | |
355 MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) { | |
356 lock_.AssertAcquired(); | |
357 DCHECK(!is_closed_); | |
358 // By default, not supported. Only needed for data pipe dispatchers. | |
359 return MOJO_RESULT_INVALID_ARGUMENT; | |
360 } | |
361 | |
362 MojoResult Dispatcher::ReadDataImplNoLock(void* /*elements*/, | |
363 uint32_t* /*num_bytes*/, | |
364 MojoReadDataFlags /*flags*/) { | |
365 lock_.AssertAcquired(); | |
366 DCHECK(!is_closed_); | |
367 // By default, not supported. Only needed for data pipe dispatchers. | |
368 return MOJO_RESULT_INVALID_ARGUMENT; | |
369 } | |
370 | |
371 MojoResult Dispatcher::BeginReadDataImplNoLock( | |
372 const void** /*buffer*/, | |
373 uint32_t* /*buffer_num_bytes*/, | |
374 MojoReadDataFlags /*flags*/) { | |
375 lock_.AssertAcquired(); | |
376 DCHECK(!is_closed_); | |
377 // By default, not supported. Only needed for data pipe dispatchers. | |
378 return MOJO_RESULT_INVALID_ARGUMENT; | |
379 } | |
380 | |
381 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) { | |
382 lock_.AssertAcquired(); | |
383 DCHECK(!is_closed_); | |
384 // By default, not supported. Only needed for data pipe dispatchers. | |
385 return MOJO_RESULT_INVALID_ARGUMENT; | |
386 } | |
387 | |
388 MojoResult Dispatcher::DuplicateBufferHandleImplNoLock( | |
389 const MojoDuplicateBufferHandleOptions* /*options*/, | |
390 scoped_refptr<Dispatcher>* /*new_dispatcher*/) { | |
391 lock_.AssertAcquired(); | |
392 DCHECK(!is_closed_); | |
393 // By default, not supported. Only needed for buffer dispatchers. | |
394 return MOJO_RESULT_INVALID_ARGUMENT; | |
395 } | |
396 | |
397 MojoResult Dispatcher::MapBufferImplNoLock( | |
398 uint64_t /*offset*/, | |
399 uint64_t /*num_bytes*/, | |
400 MojoMapBufferFlags /*flags*/, | |
401 scoped_ptr<PlatformSharedBufferMapping>* /*mapping*/) { | |
402 lock_.AssertAcquired(); | |
403 DCHECK(!is_closed_); | |
404 // By default, not supported. Only needed for buffer dispatchers. | |
405 return MOJO_RESULT_INVALID_ARGUMENT; | |
406 } | |
407 | |
408 HandleSignalsState Dispatcher::GetHandleSignalsStateImplNoLock() const { | |
409 lock_.AssertAcquired(); | |
410 DCHECK(!is_closed_); | |
411 // By default, waiting isn't supported. Only dispatchers that can be waited on | |
412 // will do something nontrivial. | |
413 return HandleSignalsState(); | |
414 } | |
415 | |
416 MojoResult Dispatcher::AddAwakableImplNoLock( | |
417 Awakable* /*awakable*/, | |
418 MojoHandleSignals /*signals*/, | |
419 uintptr_t /*context*/, | |
420 HandleSignalsState* signals_state) { | |
421 lock_.AssertAcquired(); | |
422 DCHECK(!is_closed_); | |
423 // By default, waiting isn't supported. Only dispatchers that can be waited on | |
424 // will do something nontrivial. | |
425 if (signals_state) | |
426 *signals_state = HandleSignalsState(); | |
427 return MOJO_RESULT_FAILED_PRECONDITION; | |
428 } | |
429 | |
430 MojoResult Dispatcher::AddWaitingDispatcherImplNoLock( | |
431 const scoped_refptr<Dispatcher>& /*dispatcher*/, | |
432 MojoHandleSignals /*signals*/, | |
433 uintptr_t /*context*/) { | |
434 lock_.AssertAcquired(); | |
435 DCHECK(!is_closed_); | |
436 // By default, not supported. Only needed for wait set dispatchers. | |
437 return MOJO_RESULT_INVALID_ARGUMENT; | |
438 } | |
439 | |
440 MojoResult Dispatcher::RemoveWaitingDispatcherImplNoLock( | |
441 const scoped_refptr<Dispatcher>& /*dispatcher*/) { | |
442 lock_.AssertAcquired(); | |
443 DCHECK(!is_closed_); | |
444 // By default, not supported. Only needed for wait set dispatchers. | |
445 return MOJO_RESULT_INVALID_ARGUMENT; | |
446 } | |
447 | |
448 MojoResult Dispatcher::GetReadyDispatchersImplNoLock( | |
449 uint32_t* /*count*/, | |
450 DispatcherVector* /*dispatchers*/, | |
451 MojoResult* /*results*/, | |
452 uintptr_t* /*contexts*/) { | |
453 lock_.AssertAcquired(); | |
454 DCHECK(!is_closed_); | |
455 // By default, not supported. Only needed for wait set dispatchers. | |
456 return MOJO_RESULT_INVALID_ARGUMENT; | |
457 } | |
458 | |
459 void Dispatcher::RemoveAwakableImplNoLock(Awakable* /*awakable*/, | |
460 HandleSignalsState* signals_state) { | |
461 lock_.AssertAcquired(); | |
462 DCHECK(!is_closed_); | |
463 // By default, waiting isn't supported. Only dispatchers that can be waited on | |
464 // will do something nontrivial. | |
465 if (signals_state) | |
466 *signals_state = HandleSignalsState(); | |
467 } | |
468 | |
469 void Dispatcher::StartSerializeImplNoLock(size_t* max_size, | |
470 size_t* max_platform_handles) { | |
471 DCHECK(!is_closed_); | |
472 *max_size = 0; | |
473 *max_platform_handles = 0; | |
474 } | |
475 | |
476 bool Dispatcher::EndSerializeAndCloseImplNoLock( | |
477 void* /*destination*/, | |
478 size_t* /*actual_size*/, | |
479 PlatformHandleVector* /*platform_handles*/) { | |
480 DCHECK(is_closed_); | |
481 // By default, serializing isn't supported, so just close. | |
482 CloseImplNoLock(); | |
483 return false; | |
484 } | |
485 | |
486 bool Dispatcher::IsBusyNoLock() const { | |
487 lock_.AssertAcquired(); | |
488 DCHECK(!is_closed_); | |
489 // Most dispatchers support only "atomic" operations, so they are never busy | |
490 // (in this sense). | |
491 return false; | |
492 } | |
493 | |
494 void Dispatcher::CloseNoLock() { | |
495 lock_.AssertAcquired(); | |
496 DCHECK(!is_closed_); | |
497 | |
498 is_closed_ = true; | |
499 CancelAllAwakablesNoLock(); | |
500 CloseImplNoLock(); | |
501 } | |
502 | |
503 scoped_refptr<Dispatcher> | |
504 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { | |
505 lock_.AssertAcquired(); | |
506 DCHECK(!is_closed_); | |
507 | |
508 is_closed_ = true; | |
509 CancelAllAwakablesNoLock(); | |
510 return CreateEquivalentDispatcherAndCloseImplNoLock(); | |
511 } | |
512 | |
513 void Dispatcher::StartSerialize(size_t* max_size, | |
514 size_t* max_platform_handles) { | |
515 DCHECK(max_size); | |
516 DCHECK(max_platform_handles); | |
517 DCHECK(!is_closed_); | |
518 base::AutoLock locker(lock_); | |
519 StartSerializeImplNoLock(max_size, max_platform_handles); | |
520 } | |
521 | |
522 bool Dispatcher::EndSerializeAndClose(void* destination, | |
523 size_t* actual_size, | |
524 PlatformHandleVector* platform_handles) { | |
525 DCHECK(actual_size); | |
526 DCHECK(!is_closed_); | |
527 | |
528 // Like other |...Close()| methods, we mark ourselves as closed before calling | |
529 // the impl. But there's no need to cancel waiters: we shouldn't have any (and | |
530 // shouldn't be in |Core|'s handle table. | |
531 is_closed_ = true; | |
532 | |
533 base::AutoLock locker(lock_); | |
534 return EndSerializeAndCloseImplNoLock(destination, actual_size, | |
535 platform_handles); | |
536 } | |
537 | |
538 // DispatcherTransport --------------------------------------------------------- | |
539 | |
540 void DispatcherTransport::End() { | |
541 DCHECK(dispatcher_); | |
542 dispatcher_->lock_.Release(); | |
543 | |
544 dispatcher_->TransportEnded(); | |
545 | |
546 dispatcher_ = nullptr; | |
547 } | |
548 | 179 |
549 } // namespace edk | 180 } // namespace edk |
550 } // namespace mojo | 181 } // namespace mojo |
OLD | NEW |