Index: mojo/edk/system/watcher.h |
diff --git a/mojo/edk/system/watcher.h b/mojo/edk/system/watcher.h |
index b6dc2e4645ad0e8d0d88fa571fedceb78ef97e9f..7a3903bbb3b4b86e79935640c910e8dae2d26b0e 100644 |
--- a/mojo/edk/system/watcher.h |
+++ b/mojo/edk/system/watcher.h |
@@ -9,6 +9,7 @@ |
#include "base/macros.h" |
#include "base/memory/ref_counted.h" |
#include "base/synchronization/lock.h" |
+#include "mojo/edk/system/atomic_flag.h" |
#include "mojo/public/c/system/functions.h" |
#include "mojo/public/c/system/types.h" |
@@ -17,13 +18,14 @@ namespace edk { |
struct HandleSignalsState; |
-// This object corresponds to a watch added by a single call to |MojoWatch()|. |
+// This object corresponds to a watcher added by a single call to |
+// |MojoRegisterWatcher()|. |
// |
// An event may occur at any time which should trigger a Watcher to run its |
// callback, but the callback needs to be deferred until all EDK locks are |
-// released. At the same time, a watch may be cancelled at any time by |
-// |MojoCancelWatch()| and it is not OK for the callback to be invoked after |
-// that happens. |
+// released. At the same time, a watcher may be unregistered at any time by |
+// |MojoUnregisterWatcher()| and it is not OK for the callback to be invoked |
+// after that happens. |
// |
// Therefore a Watcher needs to have some associated thread-safe state to track |
// its cancellation, which is why it's ref-counted. |
@@ -44,16 +46,27 @@ class Watcher : public base::RefCountedThreadSafe<Watcher> { |
const HandleSignalsState& state, |
MojoWatchNotificationFlags flags); |
- // Notifies the Watcher of a state change. This may result in the Watcher |
- // adding a finalizer to the current RequestContext to invoke its callback, |
- // cancellation notwithstanding. |
- void NotifyForStateChange(const HandleSignalsState& signals_state); |
+ // Notifies the Watcher of the handle's current signals state. This may result |
+ // in the Watcher adding a finalizer to the current RequestContext to invoke |
+ // its callback if the watcher is currently armed and not cancelled by the |
+ // the time the RequestContext is unwound. |
+ void NotifyState(const HandleSignalsState& signals_state); |
// Notifies the Watcher of handle closure. This always results in the Watcher |
- // adding a finalizer to the current RequestContext to invoke its callback, |
- // cancellation notwithstanding. |
+ // adding a finalizer to the current RequestContext to invoke its callback |
+ // if the watcher has not been cancelled by the time the RequestContextd is |
+ // unwound. |
void NotifyClosed(); |
+ // Arms the watch, ensuring that any relevant future state changes will elicit |
+ // a single new notification. Returns MOJO_RESULT_OK, or some other error |
+ // code otherwise. See documentation for the public |MojoArmWatcher()| API for |
+ // details. |
+ // |
+ // |current_state| must reflect the state of the handle at the time of this |
+ // call. |
+ MojoResult Arm(const HandleSignalsState& current_state); |
+ |
// Explicitly cancels the watch, guaranteeing that its callback will never be |
// be invoked again. |
void Cancel(); |
@@ -70,8 +83,12 @@ class Watcher : public base::RefCountedThreadSafe<Watcher> { |
// |signals_| are satisfied or become permanently unsatisfiable. |
const WatchCallback callback_; |
- // Guards |is_cancelled_|. |
- base::Lock lock_; |
+ // Tracks whether or not the watcher is armed. |
+ AtomicFlag is_armed_; |
+ |
+ // Guards |is_cancelled_| and provides mutual exclusion for the notification |
+ // callback and cancellation events. |
+ base::Lock notification_lock_; |
// Indicates whether the watch has been cancelled. A |Watcher| may exist for a |
// brief period of time after being cancelled if it's been attached as a |