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

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

Issue 779503003: Extract Awakable from Waiter (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Review Update 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 a |AwakableList| that's either
viettrungluu 2014/12/03 22:31:27 "a" -> "an"
Hajime Morrita 2014/12/03 22:47:11 Done.
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 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
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