Index: mojo/edk/system/request_context.cc |
diff --git a/mojo/edk/system/request_context.cc b/mojo/edk/system/request_context.cc |
index c30d8bb821c501af2d424baac908ef6130b742d4..f4f70b5ec1fff6325884d377ca907f90ff5a159b 100644 |
--- a/mojo/edk/system/request_context.cc |
+++ b/mojo/edk/system/request_context.cc |
@@ -18,7 +18,10 @@ base::LazyInstance<base::ThreadLocalPointer<RequestContext>>::Leaky |
} // namespace |
-RequestContext::RequestContext() : tls_context_(g_current_context.Pointer()){ |
+RequestContext::RequestContext() : RequestContext(Source::LOCAL_API_CALL) {} |
+ |
+RequestContext::RequestContext(Source source) |
+ : source_(source), tls_context_(g_current_context.Pointer()) { |
// We allow nested RequestContexts to exist as long as they aren't actually |
// used for anything. |
if (!tls_context_->Get()) |
@@ -26,23 +29,34 @@ RequestContext::RequestContext() : tls_context_(g_current_context.Pointer()){ |
} |
RequestContext::~RequestContext() { |
- // NOTE: Callbacks invoked by this destructor are allowed to initiate new |
- // EDK requests on this thread, so we need to reset the thread-local context |
- // pointer before calling them. |
- if (IsCurrent()) |
+ if (IsCurrent()) { |
+ // NOTE: Callbacks invoked by this destructor are allowed to initiate new |
+ // EDK requests on this thread, so we need to reset the thread-local context |
+ // pointer before calling them. We persist the original notification source |
+ // since we're starting over at the bottom of the stack. |
tls_context_->Set(nullptr); |
- 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; |
- watch.watcher->MaybeInvokeCallback(watch.result, watch.state); |
+ MojoWatchNotificationFlags flags = MOJO_WATCH_NOTIFICATION_FLAG_NONE; |
+ if (source_ == Source::SYSTEM) |
+ flags |= MOJO_WATCH_NOTIFICATION_FLAG_FROM_SYSTEM; |
+ |
+ 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); |
+ } |
+ |
+ for (const scoped_refptr<Watcher>& watcher : |
+ watch_cancel_finalizers_.container()) |
+ watcher->Cancel(); |
+ } else { |
+ // It should be impossible for nested contexts to have finalizers. |
+ DCHECK(watch_notify_finalizers_.container().empty()); |
+ DCHECK(watch_cancel_finalizers_.container().empty()); |
} |
- |
- for (const scoped_refptr<Watcher>& watcher : |
- watch_cancel_finalizers_.container()) |
- watcher->Cancel(); |
} |
// static |