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

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

Issue 2088833003: Add different behavior to AwakableList for "persistent" vs "one-shot" awakables. (Closed) Base URL: https://github.com/domokit/mojo.git@work793_wait_set_4.5
Patch Set: Created 4 years, 6 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
« no previous file with comments | « mojo/edk/system/awakable_list.h ('k') | mojo/edk/system/awakable_list_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/awakable_list.h" 5 #include "mojo/edk/system/awakable_list.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "mojo/edk/system/awakable.h" 10 #include "mojo/edk/system/awakable.h"
11 #include "mojo/edk/system/handle_signals_state.h" 11 #include "mojo/edk/system/handle_signals_state.h"
12 12
13 namespace mojo { 13 namespace mojo {
14 namespace system { 14 namespace system {
15 15
16 AwakableList::AwakableList() {} 16 AwakableList::AwakableList() {}
17 17
18 AwakableList::~AwakableList() { 18 AwakableList::~AwakableList() {
19 DCHECK(awakables_.empty()); 19 DCHECK(awakables_.empty());
20 } 20 }
21 21
22 void AwakableList::OnStateChange(const HandleSignalsState& old_state, 22 void AwakableList::OnStateChange(const HandleSignalsState& old_state,
23 const HandleSignalsState& new_state) { 23 const HandleSignalsState& new_state) {
24 // Instead of deleting elements in-place, swap them with the last element and 24 // Instead of deleting elements in-place, swap them with the last element and
25 // erase the elements from the end. 25 // erase the elements from the end.
26 auto last = awakables_.end(); 26 auto last = awakables_.end();
27 for (AwakeInfoList::iterator it = awakables_.begin(); it != last;) { 27 for (auto it = awakables_.begin(); it != last;) {
28 bool keep = true; 28 bool awoken = false;
29 if (new_state.satisfies(it->signals) && !old_state.satisfies(it->signals)) { 29 if (it->persistent) {
30 keep = it->awakable->Awake(it->context, Awakable::AwakeReason::SATISFIED, 30 // Persistent awakables are called for all changes on watched signals.
31 new_state); 31 if ((new_state.satisfied_signals & it->signals) !=
32 } else if (!new_state.can_satisfy(it->signals) && 32 (old_state.satisfied_signals & it->signals) ||
33 old_state.can_satisfy(it->signals)) { 33 (new_state.satisfiable_signals & it->signals) !=
34 keep = it->awakable->Awake( 34 (old_state.satisfiable_signals & it->signals)) {
35 it->context, Awakable::AwakeReason::UNSATISFIABLE, new_state); 35 awoken = true;
36 it->awakable->Awake(it->context, Awakable::AwakeReason::CHANGED,
37 new_state);
38 }
39 } else {
40 // One-shot awakables are only called on "leading edge" changes.
41 if (new_state.satisfies(it->signals) &&
42 !old_state.satisfies(it->signals)) {
43 awoken = true;
44 it->awakable->Awake(it->context, Awakable::AwakeReason::SATISFIED,
45 new_state);
46 } else if (!new_state.can_satisfy(it->signals) &&
47 old_state.can_satisfy(it->signals)) {
48 awoken = true;
49 it->awakable->Awake(it->context, Awakable::AwakeReason::UNSATISFIABLE,
50 new_state);
51 }
36 } 52 }
37 53
38 if (!keep) { 54 // Remove if the awakable was awoken and one-shot.
55 if (awoken && !it->persistent) {
39 --last; 56 --last;
40 std::swap(*it, *last); 57 std::swap(*it, *last);
41 } else { 58 } else {
42 ++it; 59 ++it;
43 } 60 }
44 } 61 }
45 awakables_.erase(last, awakables_.end()); 62 awakables_.erase(last, awakables_.end());
46 } 63 }
47 64
48 void AwakableList::CancelAll() { 65 void AwakableList::CancelAndRemoveAll() {
49 for (AwakeInfoList::iterator it = awakables_.begin(); it != awakables_.end(); 66 for (auto it = awakables_.begin(); it != awakables_.end(); ++it) {
50 ++it) {
51 it->awakable->Awake(it->context, Awakable::AwakeReason::CANCELLED, 67 it->awakable->Awake(it->context, Awakable::AwakeReason::CANCELLED,
52 HandleSignalsState()); 68 HandleSignalsState());
53 } 69 }
54 awakables_.clear(); 70 awakables_.clear();
55 } 71 }
56 72
57 void AwakableList::Add(Awakable* awakable, 73 void AwakableList::Add(Awakable* awakable,
58 uint64_t context, 74 uint64_t context,
75 bool persistent,
59 MojoHandleSignals signals) { 76 MojoHandleSignals signals) {
60 awakables_.push_back(AwakeInfo(awakable, signals, context)); 77 awakables_.push_back(AwakeInfo(awakable, context, persistent, signals));
61 } 78 }
62 79
63 void AwakableList::Remove(bool match_context, 80 void AwakableList::Remove(bool match_context,
64 Awakable* awakable, 81 Awakable* awakable,
65 uint64_t context) { 82 uint64_t context) {
66 // We allow a thread to wait on the same handle multiple times simultaneously, 83 // We allow a thread to wait on the same handle multiple times simultaneously,
67 // so we need to scan the entire list and remove all occurrences of |waiter|. 84 // so we need to scan the entire list and remove all occurrences of |waiter|.
68 auto last = awakables_.end(); 85 auto last = awakables_.end();
69 for (AwakeInfoList::iterator it = awakables_.begin(); it != last;) { 86 for (AwakeInfoList::iterator it = awakables_.begin(); it != last;) {
70 if (it->awakable == awakable && 87 if (it->awakable == awakable &&
71 (!match_context || it->context == context)) { 88 (!match_context || it->context == context)) {
72 --last; 89 --last;
73 std::swap(*it, *last); 90 std::swap(*it, *last);
74 } else { 91 } else {
75 ++it; 92 ++it;
76 } 93 }
77 } 94 }
78 awakables_.erase(last, awakables_.end()); 95 awakables_.erase(last, awakables_.end());
79 } 96 }
80 97
81 } // namespace system 98 } // namespace system
82 } // namespace mojo 99 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/awakable_list.h ('k') | mojo/edk/system/awakable_list_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698