Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: third_party/mojo/src/mojo/edk/system/dispatcher.cc

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

Powered by Google App Engine
This is Rietveld 408576698