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

Side by Side Diff: mojo/edk/system/core.cc

Issue 782693004: Update mojo sdk to rev f6c8ec07c01deebc13178d516225fd12695c3dc2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: hack mojo_system_impl gypi for android :| Created 6 years 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
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/core.h" 5 #include "mojo/edk/system/core.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
(...skipping 29 matching lines...) Expand all
40 // |MessagePipeDispatcher|) for each handle, with each handle having a strong 40 // |MessagePipeDispatcher|) for each handle, with each handle having a strong
41 // reference to the common "secondary" object (e.g., |MessagePipe|). This 41 // reference to the common "secondary" object (e.g., |MessagePipe|). This
42 // secondary object does NOT have any references to the |Dispatcher|s (even if 42 // secondary object does NOT have any references to the |Dispatcher|s (even if
43 // it did, it wouldn't be able to do anything with them due to lock order 43 // it did, it wouldn't be able to do anything with them due to lock order
44 // requirements -- see below). 44 // requirements -- see below).
45 // 45 //
46 // Waiting is implemented by having the thread that wants to wait call the 46 // Waiting is implemented by having the thread that wants to wait call the
47 // |Dispatcher|s for the handles that it wants to wait on with a |Waiter| 47 // |Dispatcher|s for the handles that it wants to wait on with a |Waiter|
48 // object; this |Waiter| object may be created on the stack of that thread or be 48 // object; this |Waiter| object may be created on the stack of that thread or be
49 // kept in thread local storage for that thread (TODO(vtl): future improvement). 49 // kept in thread local storage for that thread (TODO(vtl): future improvement).
50 // The |Dispatcher| then adds the |Waiter| to a |WaiterList| that's either owned 50 // The |Dispatcher| then adds the |Waiter| to an |AwakableList| that's either
51 // by that |Dispatcher| (see |SimpleDispatcher|) or by a secondary object (e.g., 51 // owned by that |Dispatcher| (see |SimpleDispatcher|) or by a secondary object
52 // |MessagePipe|). To signal/wake a |Waiter|, the object in question -- either a 52 // (e.g., |MessagePipe|). To signal/wake a |Waiter|, the object in question --
53 // |SimpleDispatcher| or a secondary object -- talks to its |WaiterList|. 53 // either a |SimpleDispatcher| or a secondary object -- talks to its
54 // |AwakableList|.
54 55
55 // Thread-safety notes 56 // Thread-safety notes
56 // 57 //
57 // Mojo primitives calls are thread-safe. We achieve this with relatively 58 // Mojo primitives calls are thread-safe. We achieve this with relatively
58 // fine-grained locking. There is a global handle table lock. This lock should 59 // fine-grained locking. There is a global handle table lock. This lock should
59 // be held as briefly as possible (TODO(vtl): a future improvement would be to 60 // be held as briefly as possible (TODO(vtl): a future improvement would be to
60 // switch it to a reader-writer lock). Each |Dispatcher| object then has a lock 61 // switch it to a reader-writer lock). Each |Dispatcher| object then has a lock
61 // (which subclasses can use to protect their data). 62 // (which subclasses can use to protect their data).
62 // 63 //
63 // The lock ordering is as follows: 64 // The lock ordering is as follows:
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 // isn't done, in the in-process case, calls on the old handle may complete 215 // isn't done, in the in-process case, calls on the old handle may complete
215 // after the the message has been received and a new handle created (and 216 // after the the message has been received and a new handle created (and
216 // possibly even after calls have been made on the new handle). 217 // possibly even after calls have been made on the new handle).
217 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, 218 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle,
218 UserPointer<const void> bytes, 219 UserPointer<const void> bytes,
219 uint32_t num_bytes, 220 uint32_t num_bytes,
220 UserPointer<const MojoHandle> handles, 221 UserPointer<const MojoHandle> handles,
221 uint32_t num_handles, 222 uint32_t num_handles,
222 MojoWriteMessageFlags flags) { 223 MojoWriteMessageFlags flags) {
223 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); 224 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle));
224 if (!dispatcher.get()) 225 if (!dispatcher)
225 return MOJO_RESULT_INVALID_ARGUMENT; 226 return MOJO_RESULT_INVALID_ARGUMENT;
226 227
227 // Easy case: not sending any handles. 228 // Easy case: not sending any handles.
228 if (num_handles == 0) 229 if (num_handles == 0)
229 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, flags); 230 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, flags);
230 231
231 // We have to handle |handles| here, since we have to mark them busy in the 232 // We have to handle |handles| here, since we have to mark them busy in the
232 // global handle table. We can't delegate this to the dispatcher, since the 233 // global handle table. We can't delegate this to the dispatcher, since the
233 // handle table lock must be acquired before the dispatcher lock. 234 // handle table lock must be acquired before the dispatcher lock.
234 // 235 //
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 return rv; 282 return rv;
282 } 283 }
283 284
284 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, 285 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle,
285 UserPointer<void> bytes, 286 UserPointer<void> bytes,
286 UserPointer<uint32_t> num_bytes, 287 UserPointer<uint32_t> num_bytes,
287 UserPointer<MojoHandle> handles, 288 UserPointer<MojoHandle> handles,
288 UserPointer<uint32_t> num_handles, 289 UserPointer<uint32_t> num_handles,
289 MojoReadMessageFlags flags) { 290 MojoReadMessageFlags flags) {
290 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle)); 291 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(message_pipe_handle));
291 if (!dispatcher.get()) 292 if (!dispatcher)
292 return MOJO_RESULT_INVALID_ARGUMENT; 293 return MOJO_RESULT_INVALID_ARGUMENT;
293 294
294 uint32_t num_handles_value = num_handles.IsNull() ? 0 : num_handles.Get(); 295 uint32_t num_handles_value = num_handles.IsNull() ? 0 : num_handles.Get();
295 296
296 MojoResult rv; 297 MojoResult rv;
297 if (num_handles_value == 0) { 298 if (num_handles_value == 0) {
298 // Easy case: won't receive any handles. 299 // Easy case: won't receive any handles.
299 rv = dispatcher->ReadMessage(bytes, num_bytes, nullptr, &num_handles_value, 300 rv = dispatcher->ReadMessage(bytes, num_bytes, nullptr, &num_handles_value,
300 flags); 301 flags);
301 } else { 302 } else {
(...skipping 13 matching lines...) Expand all
315 success = handle_table_.AddDispatcherVector( 316 success = handle_table_.AddDispatcherVector(
316 dispatchers, handles_writer.GetPointer()); 317 dispatchers, handles_writer.GetPointer());
317 } 318 }
318 if (success) { 319 if (success) {
319 handles_writer.Commit(); 320 handles_writer.Commit();
320 } else { 321 } else {
321 LOG(ERROR) << "Received message with " << dispatchers.size() 322 LOG(ERROR) << "Received message with " << dispatchers.size()
322 << " handles, but handle table full"; 323 << " handles, but handle table full";
323 // Close dispatchers (outside the lock). 324 // Close dispatchers (outside the lock).
324 for (size_t i = 0; i < dispatchers.size(); i++) { 325 for (size_t i = 0; i < dispatchers.size(); i++) {
325 if (dispatchers[i].get()) 326 if (dispatchers[i])
326 dispatchers[i]->Close(); 327 dispatchers[i]->Close();
327 } 328 }
328 if (rv == MOJO_RESULT_OK) 329 if (rv == MOJO_RESULT_OK)
329 rv = MOJO_RESULT_RESOURCE_EXHAUSTED; 330 rv = MOJO_RESULT_RESOURCE_EXHAUSTED;
330 } 331 }
331 } 332 }
332 } 333 }
333 334
334 if (!num_handles.IsNull()) 335 if (!num_handles.IsNull())
335 num_handles.Put(num_handles_value); 336 num_handles.Put(num_handles_value);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 data_pipe_consumer_handle.Put(handle_pair.second); 375 data_pipe_consumer_handle.Put(handle_pair.second);
375 return MOJO_RESULT_OK; 376 return MOJO_RESULT_OK;
376 } 377 }
377 378
378 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, 379 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle,
379 UserPointer<const void> elements, 380 UserPointer<const void> elements,
380 UserPointer<uint32_t> num_bytes, 381 UserPointer<uint32_t> num_bytes,
381 MojoWriteDataFlags flags) { 382 MojoWriteDataFlags flags) {
382 scoped_refptr<Dispatcher> dispatcher( 383 scoped_refptr<Dispatcher> dispatcher(
383 GetDispatcher(data_pipe_producer_handle)); 384 GetDispatcher(data_pipe_producer_handle));
384 if (!dispatcher.get()) 385 if (!dispatcher)
385 return MOJO_RESULT_INVALID_ARGUMENT; 386 return MOJO_RESULT_INVALID_ARGUMENT;
386 387
387 return dispatcher->WriteData(elements, num_bytes, flags); 388 return dispatcher->WriteData(elements, num_bytes, flags);
388 } 389 }
389 390
390 MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle, 391 MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle,
391 UserPointer<void*> buffer, 392 UserPointer<void*> buffer,
392 UserPointer<uint32_t> buffer_num_bytes, 393 UserPointer<uint32_t> buffer_num_bytes,
393 MojoWriteDataFlags flags) { 394 MojoWriteDataFlags flags) {
394 scoped_refptr<Dispatcher> dispatcher( 395 scoped_refptr<Dispatcher> dispatcher(
395 GetDispatcher(data_pipe_producer_handle)); 396 GetDispatcher(data_pipe_producer_handle));
396 if (!dispatcher.get()) 397 if (!dispatcher)
397 return MOJO_RESULT_INVALID_ARGUMENT; 398 return MOJO_RESULT_INVALID_ARGUMENT;
398 399
399 return dispatcher->BeginWriteData(buffer, buffer_num_bytes, flags); 400 return dispatcher->BeginWriteData(buffer, buffer_num_bytes, flags);
400 } 401 }
401 402
402 MojoResult Core::EndWriteData(MojoHandle data_pipe_producer_handle, 403 MojoResult Core::EndWriteData(MojoHandle data_pipe_producer_handle,
403 uint32_t num_bytes_written) { 404 uint32_t num_bytes_written) {
404 scoped_refptr<Dispatcher> dispatcher( 405 scoped_refptr<Dispatcher> dispatcher(
405 GetDispatcher(data_pipe_producer_handle)); 406 GetDispatcher(data_pipe_producer_handle));
406 if (!dispatcher.get()) 407 if (!dispatcher)
407 return MOJO_RESULT_INVALID_ARGUMENT; 408 return MOJO_RESULT_INVALID_ARGUMENT;
408 409
409 return dispatcher->EndWriteData(num_bytes_written); 410 return dispatcher->EndWriteData(num_bytes_written);
410 } 411 }
411 412
412 MojoResult Core::ReadData(MojoHandle data_pipe_consumer_handle, 413 MojoResult Core::ReadData(MojoHandle data_pipe_consumer_handle,
413 UserPointer<void> elements, 414 UserPointer<void> elements,
414 UserPointer<uint32_t> num_bytes, 415 UserPointer<uint32_t> num_bytes,
415 MojoReadDataFlags flags) { 416 MojoReadDataFlags flags) {
416 scoped_refptr<Dispatcher> dispatcher( 417 scoped_refptr<Dispatcher> dispatcher(
417 GetDispatcher(data_pipe_consumer_handle)); 418 GetDispatcher(data_pipe_consumer_handle));
418 if (!dispatcher.get()) 419 if (!dispatcher)
419 return MOJO_RESULT_INVALID_ARGUMENT; 420 return MOJO_RESULT_INVALID_ARGUMENT;
420 421
421 return dispatcher->ReadData(elements, num_bytes, flags); 422 return dispatcher->ReadData(elements, num_bytes, flags);
422 } 423 }
423 424
424 MojoResult Core::BeginReadData(MojoHandle data_pipe_consumer_handle, 425 MojoResult Core::BeginReadData(MojoHandle data_pipe_consumer_handle,
425 UserPointer<const void*> buffer, 426 UserPointer<const void*> buffer,
426 UserPointer<uint32_t> buffer_num_bytes, 427 UserPointer<uint32_t> buffer_num_bytes,
427 MojoReadDataFlags flags) { 428 MojoReadDataFlags flags) {
428 scoped_refptr<Dispatcher> dispatcher( 429 scoped_refptr<Dispatcher> dispatcher(
429 GetDispatcher(data_pipe_consumer_handle)); 430 GetDispatcher(data_pipe_consumer_handle));
430 if (!dispatcher.get()) 431 if (!dispatcher)
431 return MOJO_RESULT_INVALID_ARGUMENT; 432 return MOJO_RESULT_INVALID_ARGUMENT;
432 433
433 return dispatcher->BeginReadData(buffer, buffer_num_bytes, flags); 434 return dispatcher->BeginReadData(buffer, buffer_num_bytes, flags);
434 } 435 }
435 436
436 MojoResult Core::EndReadData(MojoHandle data_pipe_consumer_handle, 437 MojoResult Core::EndReadData(MojoHandle data_pipe_consumer_handle,
437 uint32_t num_bytes_read) { 438 uint32_t num_bytes_read) {
438 scoped_refptr<Dispatcher> dispatcher( 439 scoped_refptr<Dispatcher> dispatcher(
439 GetDispatcher(data_pipe_consumer_handle)); 440 GetDispatcher(data_pipe_consumer_handle));
440 if (!dispatcher.get()) 441 if (!dispatcher)
441 return MOJO_RESULT_INVALID_ARGUMENT; 442 return MOJO_RESULT_INVALID_ARGUMENT;
442 443
443 return dispatcher->EndReadData(num_bytes_read); 444 return dispatcher->EndReadData(num_bytes_read);
444 } 445 }
445 446
446 MojoResult Core::CreateSharedBuffer( 447 MojoResult Core::CreateSharedBuffer(
447 UserPointer<const MojoCreateSharedBufferOptions> options, 448 UserPointer<const MojoCreateSharedBufferOptions> options,
448 uint64_t num_bytes, 449 uint64_t num_bytes,
449 UserPointer<MojoHandle> shared_buffer_handle) { 450 UserPointer<MojoHandle> shared_buffer_handle) {
450 MojoCreateSharedBufferOptions validated_options = {}; 451 MojoCreateSharedBufferOptions validated_options = {};
451 MojoResult result = SharedBufferDispatcher::ValidateCreateOptions( 452 MojoResult result = SharedBufferDispatcher::ValidateCreateOptions(
452 options, &validated_options); 453 options, &validated_options);
453 if (result != MOJO_RESULT_OK) 454 if (result != MOJO_RESULT_OK)
454 return result; 455 return result;
455 456
456 scoped_refptr<SharedBufferDispatcher> dispatcher; 457 scoped_refptr<SharedBufferDispatcher> dispatcher;
457 result = SharedBufferDispatcher::Create(platform_support(), validated_options, 458 result = SharedBufferDispatcher::Create(platform_support(), validated_options,
458 num_bytes, &dispatcher); 459 num_bytes, &dispatcher);
459 if (result != MOJO_RESULT_OK) { 460 if (result != MOJO_RESULT_OK) {
460 DCHECK(!dispatcher.get()); 461 DCHECK(!dispatcher);
461 return result; 462 return result;
462 } 463 }
463 464
464 MojoHandle h = AddDispatcher(dispatcher); 465 MojoHandle h = AddDispatcher(dispatcher);
465 if (h == MOJO_HANDLE_INVALID) { 466 if (h == MOJO_HANDLE_INVALID) {
466 LOG(ERROR) << "Handle table full"; 467 LOG(ERROR) << "Handle table full";
467 dispatcher->Close(); 468 dispatcher->Close();
468 return MOJO_RESULT_RESOURCE_EXHAUSTED; 469 return MOJO_RESULT_RESOURCE_EXHAUSTED;
469 } 470 }
470 471
471 shared_buffer_handle.Put(h); 472 shared_buffer_handle.Put(h);
472 return MOJO_RESULT_OK; 473 return MOJO_RESULT_OK;
473 } 474 }
474 475
475 MojoResult Core::DuplicateBufferHandle( 476 MojoResult Core::DuplicateBufferHandle(
476 MojoHandle buffer_handle, 477 MojoHandle buffer_handle,
477 UserPointer<const MojoDuplicateBufferHandleOptions> options, 478 UserPointer<const MojoDuplicateBufferHandleOptions> options,
478 UserPointer<MojoHandle> new_buffer_handle) { 479 UserPointer<MojoHandle> new_buffer_handle) {
479 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); 480 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle));
480 if (!dispatcher.get()) 481 if (!dispatcher)
481 return MOJO_RESULT_INVALID_ARGUMENT; 482 return MOJO_RESULT_INVALID_ARGUMENT;
482 483
483 // Don't verify |options| here; that's the dispatcher's job. 484 // Don't verify |options| here; that's the dispatcher's job.
484 scoped_refptr<Dispatcher> new_dispatcher; 485 scoped_refptr<Dispatcher> new_dispatcher;
485 MojoResult result = 486 MojoResult result =
486 dispatcher->DuplicateBufferHandle(options, &new_dispatcher); 487 dispatcher->DuplicateBufferHandle(options, &new_dispatcher);
487 if (result != MOJO_RESULT_OK) 488 if (result != MOJO_RESULT_OK)
488 return result; 489 return result;
489 490
490 MojoHandle new_handle = AddDispatcher(new_dispatcher); 491 MojoHandle new_handle = AddDispatcher(new_dispatcher);
491 if (new_handle == MOJO_HANDLE_INVALID) { 492 if (new_handle == MOJO_HANDLE_INVALID) {
492 LOG(ERROR) << "Handle table full"; 493 LOG(ERROR) << "Handle table full";
493 dispatcher->Close(); 494 dispatcher->Close();
494 return MOJO_RESULT_RESOURCE_EXHAUSTED; 495 return MOJO_RESULT_RESOURCE_EXHAUSTED;
495 } 496 }
496 497
497 new_buffer_handle.Put(new_handle); 498 new_buffer_handle.Put(new_handle);
498 return MOJO_RESULT_OK; 499 return MOJO_RESULT_OK;
499 } 500 }
500 501
501 MojoResult Core::MapBuffer(MojoHandle buffer_handle, 502 MojoResult Core::MapBuffer(MojoHandle buffer_handle,
502 uint64_t offset, 503 uint64_t offset,
503 uint64_t num_bytes, 504 uint64_t num_bytes,
504 UserPointer<void*> buffer, 505 UserPointer<void*> buffer,
505 MojoMapBufferFlags flags) { 506 MojoMapBufferFlags flags) {
506 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); 507 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle));
507 if (!dispatcher.get()) 508 if (!dispatcher)
508 return MOJO_RESULT_INVALID_ARGUMENT; 509 return MOJO_RESULT_INVALID_ARGUMENT;
509 510
510 scoped_ptr<embedder::PlatformSharedBufferMapping> mapping; 511 scoped_ptr<embedder::PlatformSharedBufferMapping> mapping;
511 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); 512 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping);
512 if (result != MOJO_RESULT_OK) 513 if (result != MOJO_RESULT_OK)
513 return result; 514 return result;
514 515
515 DCHECK(mapping); 516 DCHECK(mapping);
516 void* address = mapping->GetBase(); 517 void* address = mapping->GetBase();
517 { 518 {
518 base::AutoLock locker(mapping_table_lock_); 519 base::AutoLock locker(mapping_table_lock_);
519 result = mapping_table_.AddMapping(mapping.Pass()); 520 result = mapping_table_.AddMapping(mapping.Pass());
520 } 521 }
521 if (result != MOJO_RESULT_OK) 522 if (result != MOJO_RESULT_OK)
522 return result; 523 return result;
523 524
524 buffer.Put(address); 525 buffer.Put(address);
525 return MOJO_RESULT_OK; 526 return MOJO_RESULT_OK;
526 } 527 }
527 528
528 MojoResult Core::UnmapBuffer(UserPointer<void> buffer) { 529 MojoResult Core::UnmapBuffer(UserPointer<void> buffer) {
529 base::AutoLock locker(mapping_table_lock_); 530 base::AutoLock locker(mapping_table_lock_);
530 return mapping_table_.RemoveMapping(buffer.GetPointerValue()); 531 return mapping_table_.RemoveMapping(buffer.GetPointerValue());
531 } 532 }
532 533
533 // Note: We allow |handles| to repeat the same handle multiple times, since 534 // Note: We allow |handles| to repeat the same handle multiple times, since
534 // different flags may be specified. 535 // different flags may be specified.
535 // TODO(vtl): This incurs a performance cost in |RemoveWaiter()|. Analyze this 536 // TODO(vtl): This incurs a performance cost in |Remove()|. Analyze this
536 // more carefully and address it if necessary. 537 // more carefully and address it if necessary.
537 MojoResult Core::WaitManyInternal(const MojoHandle* handles, 538 MojoResult Core::WaitManyInternal(const MojoHandle* handles,
538 const MojoHandleSignals* signals, 539 const MojoHandleSignals* signals,
539 uint32_t num_handles, 540 uint32_t num_handles,
540 MojoDeadline deadline, 541 MojoDeadline deadline,
541 uint32_t* result_index, 542 uint32_t* result_index,
542 HandleSignalsState* signals_states) { 543 HandleSignalsState* signals_states) {
543 DCHECK_GT(num_handles, 0u); 544 DCHECK_GT(num_handles, 0u);
544 DCHECK_EQ(*result_index, static_cast<uint32_t>(-1)); 545 DCHECK_EQ(*result_index, static_cast<uint32_t>(-1));
545 546
546 DispatcherVector dispatchers; 547 DispatcherVector dispatchers;
547 dispatchers.reserve(num_handles); 548 dispatchers.reserve(num_handles);
548 for (uint32_t i = 0; i < num_handles; i++) { 549 for (uint32_t i = 0; i < num_handles; i++) {
549 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]); 550 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]);
550 if (!dispatcher.get()) { 551 if (!dispatcher) {
551 *result_index = i; 552 *result_index = i;
552 return MOJO_RESULT_INVALID_ARGUMENT; 553 return MOJO_RESULT_INVALID_ARGUMENT;
553 } 554 }
554 dispatchers.push_back(dispatcher); 555 dispatchers.push_back(dispatcher);
555 } 556 }
556 557
557 // TODO(vtl): Should make the waiter live (permanently) in TLS. 558 // TODO(vtl): Should make the waiter live (permanently) in TLS.
558 Waiter waiter; 559 Waiter waiter;
559 waiter.Init(); 560 waiter.Init();
560 561
561 uint32_t i; 562 uint32_t i;
562 MojoResult rv = MOJO_RESULT_OK; 563 MojoResult rv = MOJO_RESULT_OK;
563 for (i = 0; i < num_handles; i++) { 564 for (i = 0; i < num_handles; i++) {
564 rv = dispatchers[i]->AddWaiter( 565 rv = dispatchers[i]->AddAwakable(
565 &waiter, signals[i], i, signals_states ? &signals_states[i] : nullptr); 566 &waiter, signals[i], i, signals_states ? &signals_states[i] : nullptr);
566 if (rv != MOJO_RESULT_OK) { 567 if (rv != MOJO_RESULT_OK) {
567 *result_index = i; 568 *result_index = i;
568 break; 569 break;
569 } 570 }
570 } 571 }
571 uint32_t num_added = i; 572 uint32_t num_added = i;
572 573
573 if (rv == MOJO_RESULT_ALREADY_EXISTS) 574 if (rv == MOJO_RESULT_ALREADY_EXISTS)
574 rv = MOJO_RESULT_OK; // The i-th one is already "triggered". 575 rv = MOJO_RESULT_OK; // The i-th one is already "triggered".
575 else if (rv == MOJO_RESULT_OK) 576 else if (rv == MOJO_RESULT_OK)
576 rv = waiter.Wait(deadline, result_index); 577 rv = waiter.Wait(deadline, result_index);
577 578
578 // Make sure no other dispatchers try to wake |waiter| for the current 579 // Make sure no other dispatchers try to wake |waiter| for the current
579 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be 580 // |Wait()|/|WaitMany()| call. (Only after doing this can |waiter| be
580 // destroyed, but this would still be required if the waiter were in TLS.) 581 // destroyed, but this would still be required if the waiter were in TLS.)
581 for (i = 0; i < num_added; i++) { 582 for (i = 0; i < num_added; i++) {
582 dispatchers[i]->RemoveWaiter(&waiter, 583 dispatchers[i]->RemoveAwakable(
583 signals_states ? &signals_states[i] : nullptr); 584 &waiter, signals_states ? &signals_states[i] : nullptr);
584 } 585 }
585 if (signals_states) { 586 if (signals_states) {
586 for (; i < num_handles; i++) 587 for (; i < num_handles; i++)
587 signals_states[i] = dispatchers[i]->GetHandleSignalsState(); 588 signals_states[i] = dispatchers[i]->GetHandleSignalsState();
588 } 589 }
589 590
590 return rv; 591 return rv;
591 } 592 }
592 593
593 } // namespace system 594 } // namespace system
594 } // namespace mojo 595 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698