Index: mojo/edk/system/watch.h |
diff --git a/mojo/edk/system/watch.h b/mojo/edk/system/watch.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6799ddbd74a3dcc62b780372e54054527f472e9e |
--- /dev/null |
+++ b/mojo/edk/system/watch.h |
@@ -0,0 +1,100 @@ |
+// Copyright 2017 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_WATCH_H_ |
+#define MOJO_EDK_SYSTEM_WATCH_H_ |
+ |
+#include "base/macros.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/synchronization/lock.h" |
+#include "mojo/edk/system/atomic_flag.h" |
+#include "mojo/edk/system/handle_signals_state.h" |
+ |
+namespace mojo { |
+namespace edk { |
+ |
+class Dispatcher; |
+class WatcherDispatcher; |
+ |
+// Encapsulates the state associated with a single watch context within a |
+// watcher. |
+// |
+// Every Watch has its own cancellation state, and is captured by RequestContext |
+// notification finalizers to avoid redundant context resolution during |
+// finalizer execution. |
+class Watch : public base::RefCountedThreadSafe<Watch> { |
+ public: |
+ // Constructs a Watch which represents a watch within |watcher| associated |
+ // with |context|, watching |dispatcher| for |signals|. |
+ Watch(const scoped_refptr<WatcherDispatcher>& watcher, |
+ const scoped_refptr<Dispatcher>& dispatcher, |
+ uintptr_t context, |
+ MojoHandleSignals signals); |
+ |
+ // Notifies the Watch of a potential state change. |
+ // |
+ // If |allowed_to_call_callback| is true, this may add a notification |
+ // finalizer to the current RequestContext to invoke the watcher's callback |
+ // with this watch's context. See return values below. |
+ // |
+ // This is called directly by WatcherDispatcher on all relevant Watch |
+ // instances whenever the watched Dispatcher notifies the WatcherDispatcher of |
+ // a state change. |
+ // |
+ // Returns: |
+ // |MOJO_RESULT_OK| if the watch would notify given |state| on its handle, |
+ // regardless of whether it actually does notify here (see above.) If |
+ // |allowed_to_call_callback| is |true| this return value indicates that |
+ // a notification finalizer was added to the current RequestContext. |
+ // |MOJO_RESULT_FAILED_PRECONDITION| if the watch would notify of permanent |
+ // unsatisfiability given |state| on its handle, regardless of whether |
+ // it actually does notify here (see above.) If |
+ // |allowed_to_call_callback| is |true| this return value indicates that |
+ // a notification finalizer was added to the current RequestContext. |
+ // |MOJO_RESULT_SHOULD_WAIT| if the watch would not notify given |state| on |
+ // its handle. In this case, no notification finalizer is ever added to |
+ // the current RequestContext. |
+ MojoResult NotifyState(const HandleSignalsState& state, |
+ bool allowed_to_call_callback); |
+ |
+ // Notifies the watch of cancellation ASAP. This will always be the last |
+ // notification sent for the watch. |
+ void Cancel(); |
+ |
+ // Finalizer method for RequestContexts. This method is invoked once for every |
+ // notification finalizer added to a RequestContext by this object. This calls |
+ // down into the WatcherDispatcher to do the actual notification call. |
+ void InvokeCallback(MojoResult result, |
+ const HandleSignalsState& state, |
+ MojoWatcherNotificationFlags flags); |
+ |
+ const scoped_refptr<Dispatcher>& dispatcher() const { return dispatcher_; } |
+ |
+ private: |
+ friend class base::RefCountedThreadSafe<Watch>; |
+ |
+ ~Watch(); |
+ |
+ const scoped_refptr<WatcherDispatcher> watcher_; |
+ const scoped_refptr<Dispatcher> dispatcher_; |
+ const uintptr_t context_; |
+ const MojoHandleSignals signals_; |
+ |
+ // Guards |is_cancelled_| below and mutually excludes individual watch |
+ // notification executions for this same watch context. |
+ // |
+ // Note that this should only be acquired from a RequestContext finalizer to |
+ // ensure that no other internal locks are already held. |
+ base::Lock notification_lock_; |
+ |
+ // Guarded by |notification_lock_|. |
+ bool is_cancelled_ = false; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Watch); |
+}; |
+ |
+} // namespace edk |
+} // namespace mojo |
+ |
+#endif // MOJO_EDK_SYSTEM_WATCH_H_ |