Index: mojo/edk/system/request_context.h |
diff --git a/mojo/edk/system/request_context.h b/mojo/edk/system/request_context.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..14cc1dd7cfa65f2b14b6bf27995c0da770612e98 |
--- /dev/null |
+++ b/mojo/edk/system/request_context.h |
@@ -0,0 +1,72 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef MOJO_EDK_SYSTEM_REQUEST_CONTEXT_H_ |
+#define MOJO_EDK_SYSTEM_REQUEST_CONTEXT_H_ |
+ |
+#include "base/containers/stack_container.h" |
+#include "mojo/edk/system/watcher.h" |
+ |
+namespace mojo { |
+namespace edk { |
+ |
+// A RequestContext is a thread-local object which exists for the duration of |
+// a single system API call. It is constructed immediately upon EDK entry and |
+// destructed immediately before returning to the caller, after any internal |
+// locks have been released. |
+// |
+// NOTE: It is legal to construct a RequestContext while another one already |
Anand Mistry (off Chromium)
2016/03/01 07:30:40
Are there any specific cases where this happens ri
Ken Rockot(use gerrit already)
2016/03/01 08:17:44
So if you WriteMessage to a pipe endpoint whose pe
Anand Mistry (off Chromium)
2016/03/02 01:50:35
This approach is good. The thing that confused me
|
+// exists on the current thread, but it is not safe to use the nested context |
+// for any reason. Therefore it is important to always use |
+// |RequestContext::current()| rather than referring to any local instance |
+// directly. |
+class RequestContext { |
+ public: |
+ RequestContext(); |
+ ~RequestContext(); |
+ |
+ // Returns the current thread-local RequestContext. |
+ static RequestContext* current(); |
+ |
+ // Adds a finalizer to this RequestContext corresponding to a watch callback |
+ // which should be triggered in response to some handle state change. If |
+ // the Watcher hasn't been cancelled by the time this RequestContext is |
+ // destroyed, its WatchCallback will be invoked with |result| and |state| |
+ // arguments. |
+ void AddWatchFinalizer(scoped_refptr<Watcher> watcher, |
+ MojoResult result, |
+ MojoHandleSignalsState state); |
+ |
+ private: |
+ // Is this request context the current one? |
+ bool IsCurrent() const; |
+ |
+ struct WatchFinalizer { |
+ WatchFinalizer(scoped_refptr<Watcher> watcher, |
+ MojoResult result, |
+ MojoHandleSignalsState state); |
+ ~WatchFinalizer(); |
+ |
+ scoped_refptr<Watcher> watcher; |
+ MojoResult result; |
+ MojoHandleSignalsState state; |
+ }; |
+ |
+ // Chosen by fair dice roll. |
+ // |
+ // TODO: We should measure the distribution of # of finalizers typical to |
+ // any RequestContext and adjust this number accordingly. It's probably |
+ // almost always 1, but 4 seems like a harmless upper bound for now. |
+ static const size_t kStaticWatchFinalizersCapacity = 4; |
+ |
+ using WatchFinalizerList = |
+ base::StackVector<WatchFinalizer, kStaticWatchFinalizersCapacity>; |
+ |
+ WatchFinalizerList watch_finalizers_; |
+}; |
Anand Mistry (off Chromium)
2016/03/01 07:30:40
DISALLOW_COPY_AND_ASSIGN
Ken Rockot(use gerrit already)
2016/03/01 08:17:44
Done
|
+ |
+} // namespace edk |
+} // namespace mojo |
+ |
+#endif // MOJO_EDK_SYSTEM_REQUEST_CONTEXT_H_ |