OLD | NEW |
| (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 "mojo/edk/system/awakable_list.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/logging.h" | |
10 #include "mojo/edk/system/awakable.h" | |
11 | |
12 namespace mojo { | |
13 namespace edk { | |
14 | |
15 AwakableList::AwakableList() { | |
16 } | |
17 | |
18 AwakableList::~AwakableList() { | |
19 DCHECK(awakables_.empty()); | |
20 } | |
21 | |
22 void AwakableList::AwakeForStateChange(const HandleSignalsState& state) { | |
23 // Instead of deleting elements in-place, swap them with the last element and | |
24 // erase the elements from the end. | |
25 auto last = awakables_.end(); | |
26 for (AwakeInfoList::iterator it = awakables_.begin(); it != last;) { | |
27 bool keep = true; | |
28 if (state.satisfies(it->signals)) | |
29 keep = it->awakable->Awake(MOJO_RESULT_OK, it->context); | |
30 else if (!state.can_satisfy(it->signals)) | |
31 keep = it->awakable->Awake(MOJO_RESULT_FAILED_PRECONDITION, it->context); | |
32 | |
33 if (!keep) { | |
34 --last; | |
35 std::swap(*it, *last); | |
36 } else { | |
37 ++it; | |
38 } | |
39 } | |
40 awakables_.erase(last, awakables_.end()); | |
41 } | |
42 | |
43 void AwakableList::CancelAll() { | |
44 for (AwakeInfoList::iterator it = awakables_.begin(); it != awakables_.end(); | |
45 ++it) { | |
46 it->awakable->Awake(MOJO_RESULT_CANCELLED, it->context); | |
47 } | |
48 awakables_.clear(); | |
49 } | |
50 | |
51 void AwakableList::Add(Awakable* awakable, | |
52 MojoHandleSignals signals, | |
53 uintptr_t context) { | |
54 awakables_.push_back(AwakeInfo(awakable, signals, context)); | |
55 } | |
56 | |
57 void AwakableList::Remove(Awakable* awakable) { | |
58 // We allow a thread to wait on the same handle multiple times simultaneously, | |
59 // so we need to scan the entire list and remove all occurrences of |waiter|. | |
60 auto last = awakables_.end(); | |
61 for (AwakeInfoList::iterator it = awakables_.begin(); it != last;) { | |
62 if (it->awakable == awakable) { | |
63 --last; | |
64 std::swap(*it, *last); | |
65 } else { | |
66 ++it; | |
67 } | |
68 } | |
69 awakables_.erase(last, awakables_.end()); | |
70 } | |
71 | |
72 } // namespace edk | |
73 } // namespace mojo | |
OLD | NEW |