| 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;
|
|
|