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

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

Issue 2725133002: Mojo: Armed Watchers (Closed)
Patch Set: rebase Created 3 years, 9 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/watcher_set.h" 5 #include "mojo/edk/system/watcher_set.h"
6 6
7 #include "mojo/edk/system/request_context.h" 7 #include <utility>
8 #include "mojo/public/c/system/types.h"
9 8
10 namespace mojo { 9 namespace mojo {
11 namespace edk { 10 namespace edk {
12 11
13 WatcherSet::WatcherSet() {} 12 WatcherSet::WatcherSet(Dispatcher* owner) : owner_(owner) {}
14 13
15 WatcherSet::~WatcherSet() {} 14 WatcherSet::~WatcherSet() = default;
16 15
17 void WatcherSet::NotifyForStateChange(const HandleSignalsState& state) { 16 void WatcherSet::NotifyState(const HandleSignalsState& state) {
17 // Avoid notifying watchers if they have already seen this state.
18 if (last_known_state_.has_value() && state.equals(last_known_state_.value()))
19 return;
20 last_known_state_ = state;
18 for (const auto& entry : watchers_) 21 for (const auto& entry : watchers_)
19 entry.second->NotifyForStateChange(state); 22 entry.first->NotifyHandleState(owner_, state);
20 } 23 }
21 24
22 void WatcherSet::NotifyClosed() { 25 void WatcherSet::NotifyClosed() {
23 for (const auto& entry : watchers_) 26 for (const auto& entry : watchers_)
24 entry.second->NotifyClosed(); 27 entry.first->NotifyHandleClosed(owner_);
25 } 28 }
26 29
27 MojoResult WatcherSet::Add(MojoHandleSignals signals, 30 MojoResult WatcherSet::Add(const scoped_refptr<WatcherDispatcher>& watcher,
28 const Watcher::WatchCallback& callback,
29 uintptr_t context, 31 uintptr_t context,
30 const HandleSignalsState& current_state) { 32 const HandleSignalsState& current_state) {
31 auto it = watchers_.find(context); 33 auto it = watchers_.find(watcher.get());
32 if (it != watchers_.end()) 34 if (it == watchers_.end()) {
35 auto result =
36 watchers_.insert(std::make_pair(watcher.get(), Entry{watcher}));
37 it = result.first;
38 }
39
40 if (!it->second.contexts.insert(context).second)
33 return MOJO_RESULT_ALREADY_EXISTS; 41 return MOJO_RESULT_ALREADY_EXISTS;
34 42
35 if (!current_state.can_satisfy(signals)) 43 if (last_known_state_.has_value() &&
36 return MOJO_RESULT_FAILED_PRECONDITION; 44 !current_state.equals(last_known_state_.value())) {
45 // This new state may be relevant to everyone, in which case we just
46 // notify everyone.
47 NotifyState(current_state);
48 } else {
49 // Otherwise only notify the newly added Watcher.
50 watcher->NotifyHandleState(owner_, current_state);
51 }
52 return MOJO_RESULT_OK;
53 }
37 54
38 scoped_refptr<Watcher> watcher(new Watcher(signals, callback)); 55 MojoResult WatcherSet::Remove(WatcherDispatcher* watcher, uintptr_t context) {
39 watchers_.insert(std::make_pair(context, watcher)); 56 auto it = watchers_.find(watcher);
57 if (it == watchers_.end())
58 return MOJO_RESULT_NOT_FOUND;
40 59
41 watcher->NotifyForStateChange(current_state); 60 ContextSet& contexts = it->second.contexts;
61 auto context_it = contexts.find(context);
62 if (context_it == contexts.end())
63 return MOJO_RESULT_NOT_FOUND;
64
65 contexts.erase(context_it);
66 if (contexts.empty())
67 watchers_.erase(it);
42 68
43 return MOJO_RESULT_OK; 69 return MOJO_RESULT_OK;
44 } 70 }
45 71
46 MojoResult WatcherSet::Remove(uintptr_t context) { 72 WatcherSet::Entry::Entry(const scoped_refptr<WatcherDispatcher>& dispatcher)
47 auto it = watchers_.find(context); 73 : dispatcher(dispatcher) {}
48 if (it == watchers_.end())
49 return MOJO_RESULT_INVALID_ARGUMENT;
50 74
51 RequestContext::current()->AddWatchCancelFinalizer(it->second); 75 WatcherSet::Entry::Entry(Entry&& other) = default;
52 watchers_.erase(it); 76
53 return MOJO_RESULT_OK; 77 WatcherSet::Entry::~Entry() = default;
54 } 78
79 WatcherSet::Entry& WatcherSet::Entry::operator=(Entry&& other) = default;
55 80
56 } // namespace edk 81 } // namespace edk
57 } // namespace mojo 82 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698