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

Unified Diff: mojo/edk/system/request_context.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 side-by-side diff with in-line comments
Download patch
Index: mojo/edk/system/request_context.cc
diff --git a/mojo/edk/system/request_context.cc b/mojo/edk/system/request_context.cc
index 6370ab11c77f4464d4caf8226b4e6209867721e7..5de65d7b641521fa64ea00e57257c5ae12802fcc 100644
--- a/mojo/edk/system/request_context.cc
+++ b/mojo/edk/system/request_context.cc
@@ -36,27 +36,34 @@ RequestContext::~RequestContext() {
// since we're starting over at the bottom of the stack.
tls_context_->Set(nullptr);
- MojoWatchNotificationFlags flags = MOJO_WATCH_NOTIFICATION_FLAG_NONE;
+ MojoWatcherNotificationFlags flags = MOJO_WATCHER_NOTIFICATION_FLAG_NONE;
if (source_ == Source::SYSTEM)
- flags |= MOJO_WATCH_NOTIFICATION_FLAG_FROM_SYSTEM;
+ flags |= MOJO_WATCHER_NOTIFICATION_FLAG_FROM_SYSTEM;
- // We run all cancellation finalizers first. This is necessary because it's
- // possible that one of the cancelled watchers has other pending finalizers
+ // We send all cancellation notifications first. This is necessary because
+ // it's possible that cancelled watches have other pending notifications
// attached to this RequestContext.
//
- // From the application's perspective the watch has already been cancelled,
- // so we have to honor our contract which guarantees no more notifications.
- for (const scoped_refptr<Watcher>& watcher :
- watch_cancel_finalizers_.container())
- watcher->Cancel();
+ // From the application's perspective the watch is cancelled as soon as this
+ // notification is received, and dispatching the cancellation notification
+ // updates some internal Watch state to ensure no further notifications
+ // fire. Because notifications on a single Watch are mutually exclusive,
+ // this is sufficient to guarantee that MOJO_RESULT_CANCELLED is the last
+ // notification received; which is the guarantee the API makes.
+ for (const scoped_refptr<Watch>& watch :
+ watch_cancel_finalizers_.container()) {
+ static const HandleSignalsState closed_state = {0, 0};
+
+ // Establish a new RequestContext to capture and run any new notifications
+ // triggered by the callback invocation.
+ RequestContext inner_context(source_);
+ watch->InvokeCallback(MOJO_RESULT_CANCELLED, closed_state, flags);
+ }
for (const WatchNotifyFinalizer& watch :
- watch_notify_finalizers_.container()) {
- // Establish a new request context for the extent of each callback to
- // ensure that they don't themselves invoke callbacks while holding a
- // watcher lock.
- RequestContext request_context(source_);
- watch.watcher->MaybeInvokeCallback(watch.result, watch.state, flags);
+ watch_notify_finalizers_.container()) {
+ RequestContext inner_context(source_);
+ watch.watch->InvokeCallback(watch.result, watch.state, flags);
}
} else {
// It should be impossible for nested contexts to have finalizers.
@@ -71,18 +78,17 @@ RequestContext* RequestContext::current() {
return g_current_context.Pointer()->Get();
}
-void RequestContext::AddWatchNotifyFinalizer(
- scoped_refptr<Watcher> watcher,
- MojoResult result,
- const HandleSignalsState& state) {
+void RequestContext::AddWatchNotifyFinalizer(scoped_refptr<Watch> watch,
+ MojoResult result,
+ const HandleSignalsState& state) {
DCHECK(IsCurrent());
watch_notify_finalizers_->push_back(
- WatchNotifyFinalizer(std::move(watcher), result, state));
+ WatchNotifyFinalizer(std::move(watch), result, state));
}
-void RequestContext::AddWatchCancelFinalizer(scoped_refptr<Watcher> watcher) {
+void RequestContext::AddWatchCancelFinalizer(scoped_refptr<Watch> watch) {
DCHECK(IsCurrent());
- watch_cancel_finalizers_->push_back(std::move(watcher));
+ watch_cancel_finalizers_->push_back(std::move(watch));
}
bool RequestContext::IsCurrent() const {
@@ -90,10 +96,10 @@ bool RequestContext::IsCurrent() const {
}
RequestContext::WatchNotifyFinalizer::WatchNotifyFinalizer(
- scoped_refptr<Watcher> watcher,
+ scoped_refptr<Watch> watch,
MojoResult result,
const HandleSignalsState& state)
- : watcher(std::move(watcher)), result(result), state(state) {}
+ : watch(std::move(watch)), result(result), state(state) {}
RequestContext::WatchNotifyFinalizer::WatchNotifyFinalizer(
const WatchNotifyFinalizer& other) = default;

Powered by Google App Engine
This is Rietveld 408576698