| 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
|
|
|