| Index: mojo/edk/system/request_context.cc
|
| diff --git a/mojo/edk/system/request_context.cc b/mojo/edk/system/request_context.cc
|
| index 5de65d7b641521fa64ea00e57257c5ae12802fcc..6370ab11c77f4464d4caf8226b4e6209867721e7 100644
|
| --- a/mojo/edk/system/request_context.cc
|
| +++ b/mojo/edk/system/request_context.cc
|
| @@ -36,34 +36,27 @@
|
| // since we're starting over at the bottom of the stack.
|
| tls_context_->Set(nullptr);
|
|
|
| - MojoWatcherNotificationFlags flags = MOJO_WATCHER_NOTIFICATION_FLAG_NONE;
|
| + MojoWatchNotificationFlags flags = MOJO_WATCH_NOTIFICATION_FLAG_NONE;
|
| if (source_ == Source::SYSTEM)
|
| - flags |= MOJO_WATCHER_NOTIFICATION_FLAG_FROM_SYSTEM;
|
| + flags |= MOJO_WATCH_NOTIFICATION_FLAG_FROM_SYSTEM;
|
|
|
| - // We send all cancellation notifications first. This is necessary because
|
| - // it's possible that cancelled watches have other pending notifications
|
| + // We run all cancellation finalizers first. This is necessary because it's
|
| + // possible that one of the cancelled watchers has other pending finalizers
|
| // attached to this RequestContext.
|
| //
|
| - // 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);
|
| - }
|
| + // 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();
|
|
|
| for (const WatchNotifyFinalizer& watch :
|
| - watch_notify_finalizers_.container()) {
|
| - RequestContext inner_context(source_);
|
| - watch.watch->InvokeCallback(watch.result, watch.state, flags);
|
| + 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);
|
| }
|
| } else {
|
| // It should be impossible for nested contexts to have finalizers.
|
| @@ -78,17 +71,18 @@
|
| return g_current_context.Pointer()->Get();
|
| }
|
|
|
| -void RequestContext::AddWatchNotifyFinalizer(scoped_refptr<Watch> watch,
|
| - MojoResult result,
|
| - const HandleSignalsState& state) {
|
| +void RequestContext::AddWatchNotifyFinalizer(
|
| + scoped_refptr<Watcher> watcher,
|
| + MojoResult result,
|
| + const HandleSignalsState& state) {
|
| DCHECK(IsCurrent());
|
| watch_notify_finalizers_->push_back(
|
| - WatchNotifyFinalizer(std::move(watch), result, state));
|
| + WatchNotifyFinalizer(std::move(watcher), result, state));
|
| }
|
|
|
| -void RequestContext::AddWatchCancelFinalizer(scoped_refptr<Watch> watch) {
|
| +void RequestContext::AddWatchCancelFinalizer(scoped_refptr<Watcher> watcher) {
|
| DCHECK(IsCurrent());
|
| - watch_cancel_finalizers_->push_back(std::move(watch));
|
| + watch_cancel_finalizers_->push_back(std::move(watcher));
|
| }
|
|
|
| bool RequestContext::IsCurrent() const {
|
| @@ -96,10 +90,10 @@
|
| }
|
|
|
| RequestContext::WatchNotifyFinalizer::WatchNotifyFinalizer(
|
| - scoped_refptr<Watch> watch,
|
| + scoped_refptr<Watcher> watcher,
|
| MojoResult result,
|
| const HandleSignalsState& state)
|
| - : watch(std::move(watch)), result(result), state(state) {}
|
| + : watcher(std::move(watcher)), result(result), state(state) {}
|
|
|
| RequestContext::WatchNotifyFinalizer::WatchNotifyFinalizer(
|
| const WatchNotifyFinalizer& other) = default;
|
|
|