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