Chromium Code Reviews| Index: mojo/public/cpp/system/watcher.h |
| diff --git a/mojo/public/cpp/system/watcher.h b/mojo/public/cpp/system/watcher.h |
| index 236788b1c853139367df8b0a56b44859064219ca..db4853106c3aed5859cb8e9d21c167479a76d3f3 100644 |
| --- a/mojo/public/cpp/system/watcher.h |
| +++ b/mojo/public/cpp/system/watcher.h |
| @@ -23,6 +23,28 @@ namespace mojo { |
| // NOTE: Watchers may only be used on threads which have a running MessageLoop. |
| class MOJO_CPP_SYSTEM_EXPORT Watcher { |
| public: |
| + // Selects how this Watcher is to be armed. |
| + enum class ArmingPolicy { |
| + // The Watcher is armed automatically on Start() and rearmed again after |
| + // every invocation of the ReadyCallback. There is no need to manually call |
| + // Arm() on a Watcher using this policy. |
| + // |
| + // This provides a reasonable approximation of edge-triggered behavior, |
| + // mitigating (but not completely eliminating) the potential for redundant |
| + // notifications. |
| + // |
| + // For perfect edge-triggered behavior, use MANUAL policy and manually Arm() |
| + // the Watcher as soon as it becomes possible to do so again. |
| + AUTOMATIC, |
| + |
| + // The Watcher is never armed automatically. Arm() must be called manually |
| + // before any non-cancellation notification can be dispatched to the |
| + // ReadyCallback. Immediately before the ReadyCallback is invoked, the |
| + // Watcher is disarmed again and will require another manual call to Arm() |
| + // before the next notification can fire. |
| + MANUAL, |
| + }; |
| + |
| // A callback to be called any time a watched handle changes state in some |
| // interesting way. The |result| argument indicates one of the following |
| // conditions depending on its value: |
| @@ -37,6 +59,7 @@ class MOJO_CPP_SYSTEM_EXPORT Watcher { |
| using ReadyCallback = base::Callback<void(MojoResult result)>; |
| Watcher(const tracked_objects::Location& from_here, |
| + ArmingPolicy arming_policy, |
| scoped_refptr<base::SingleThreadTaskRunner> runner = |
| base::ThreadTaskRunnerHandle::Get()); |
| @@ -61,17 +84,35 @@ class MOJO_CPP_SYSTEM_EXPORT Watcher { |
| // closure or cancellation. |
| // |
| // Once the watch is started, |callback| may be called at any time on the |
| - // current thread until |Cancel()| is called or the handle is closed. |
| + // current thread until |Cancel()| is called or the handle is closed. Note |
| + // that |callback| will only be called for results other than |
| + // |MOJO_RESULT_CANCELLED| if the Watcher is currently armed. Use ArmingPolicy |
| + // to configure how a Watcher is armed. |
| // |
| // Destroying the Watcher implicitly calls |Cancel()|. |
| MojoResult Start(Handle handle, |
| MojoHandleSignals signals, |
| const ReadyCallback& callback); |
| - // Cancels the current watch. Once this returns, the callback previously |
| + // Cancels the current watch. Once this returns, the ReadyCallback previously |
| // passed to |Start()| will never be called again for this Watcher. |
| void Cancel(); |
| + // Manually arm the watcher. See documentation for MojoArmWatcher() for |
| + // result code details. |
| + // |
| + // This is only needed when using MANUAL ArmingPolicy (see above.) |
| + MojoResult Arm(); |
| + |
| + // Manually arm the watcher, or post a task to invoke the ReadyCallback |
| + // with the result of the failed arming attempt. This is meant as a convenient |
| + // helper for a common usage of Arm(), and it ensures that the ReadyCallback |
| + // will be invoked asynchronously again as soon as the Watcher's conditions |
| + // are satisfied, assuming the Watcher isn't cancelled first. |
| + // |
| + // Unlike Arm() above, this can never fail. |
| + void ArmOrNotify(); |
| + |
| Handle handle() const { return handle_; } |
| ReadyCallback ready_callback() const { return callback_; } |
| @@ -83,6 +124,8 @@ class MOJO_CPP_SYSTEM_EXPORT Watcher { |
| private: |
| void OnHandleReady(MojoResult result); |
| + void OnHandleReadyFromAnyThread(MojoResult result, |
| + MojoWatchNotificationFlags flags); |
| static void CallOnHandleReady(uintptr_t context, |
| MojoResult result, |
| @@ -91,6 +134,9 @@ class MOJO_CPP_SYSTEM_EXPORT Watcher { |
| base::ThreadChecker thread_checker_; |
| + // The policy used to determine how this Watcher is armed. |
| + const ArmingPolicy arming_policy_; |
| + |
| // The TaskRunner of this Watcher's owning thread. This field is safe to |
| // access from any thread. |
| const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| @@ -115,6 +161,10 @@ class MOJO_CPP_SYSTEM_EXPORT Watcher { |
| // this watcher. |
| const char* heap_profiler_tag_ = nullptr; |
| + // If this address is non-null during Watcher destruction, the value this |
| + // references is set to |true|. |
| + bool* was_deleted_flag_ = nullptr; |
|
yzshen1
2017/03/03 00:03:50
Is the reason to use this instead of DestructionTr
Ken Rockot(use gerrit already)
2017/03/03 00:37:05
N/A - using WeakPtr now.
But for the record, the
|
| + |
| base::WeakPtrFactory<Watcher> weak_factory_; |
| DISALLOW_COPY_AND_ASSIGN(Watcher); |