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..75ba61fdf6cccc2128122d368928f3be5c3a1518 |
--- /dev/null |
+++ b/mojo/edk/system/request_context.h |
@@ -0,0 +1,82 @@ |
+// 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 "base/macros.h" |
+#include "mojo/edk/system/handle_signals_state.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 |
+// 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 AddWatchNotifyFinalizer(scoped_refptr<Watcher> watcher, |
+ MojoResult result, |
+ const HandleSignalsState& state); |
+ |
+ // Adds a finalizer to this RequestContext which cancels a watch. |
+ void AddWatchCancelFinalizer(scoped_refptr<Watcher> watcher); |
+ |
+ private: |
+ // Is this request context the current one? |
+ bool IsCurrent() const; |
+ |
+ struct WatchNotifyFinalizer { |
+ WatchNotifyFinalizer(scoped_refptr<Watcher> watcher, |
+ MojoResult result, |
+ const HandleSignalsState& state); |
+ ~WatchNotifyFinalizer(); |
+ |
+ scoped_refptr<Watcher> watcher; |
+ MojoResult result; |
+ HandleSignalsState 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 WatchNotifyFinalizerList = |
+ base::StackVector<WatchNotifyFinalizer, kStaticWatchFinalizersCapacity>; |
+ using WatchCancelFinalizerList = |
+ base::StackVector<scoped_refptr<Watcher>, kStaticWatchFinalizersCapacity>; |
+ |
+ WatchNotifyFinalizerList watch_notify_finalizers_; |
+ WatchCancelFinalizerList watch_cancel_finalizers_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RequestContext); |
+}; |
+ |
+} // namespace edk |
+} // namespace mojo |
+ |
+#endif // MOJO_EDK_SYSTEM_REQUEST_CONTEXT_H_ |