Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: mojo/public/cpp/system/watcher.h

Issue 2725133002: Mojo: Armed Watchers (Closed)
Patch Set: . Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MOJO_PUBLIC_CPP_SYSTEM_WATCHER_H_ 5 #ifndef MOJO_PUBLIC_CPP_SYSTEM_WATCHER_H_
6 #define MOJO_PUBLIC_CPP_SYSTEM_WATCHER_H_ 6 #define MOJO_PUBLIC_CPP_SYSTEM_WATCHER_H_
7 7
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "base/memory/weak_ptr.h" 11 #include "base/memory/weak_ptr.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/threading/thread_checker.h" 13 #include "base/threading/thread_checker.h"
14 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/thread_task_runner_handle.h"
15 #include "mojo/public/c/system/types.h" 15 #include "mojo/public/c/system/types.h"
16 #include "mojo/public/cpp/system/handle.h" 16 #include "mojo/public/cpp/system/handle.h"
17 #include "mojo/public/cpp/system/system_export.h" 17 #include "mojo/public/cpp/system/system_export.h"
18 18
19 namespace mojo { 19 namespace mojo {
20 20
21 // A Watcher watches a single Mojo handle for signal state changes. 21 // A Watcher watches a single Mojo handle for signal state changes.
22 // 22 //
23 // NOTE: Watchers may only be used on threads which have a running MessageLoop. 23 // NOTE: Watchers may only be used on threads which have a running MessageLoop.
24 class MOJO_CPP_SYSTEM_EXPORT Watcher { 24 class MOJO_CPP_SYSTEM_EXPORT Watcher {
25 public: 25 public:
26 // Selects how this Watcher is to be armed.
27 enum class ArmingPolicy {
28 // The Watcher is armed automatically on Start() and rearmed again after
29 // every invocation of the ReadyCallback. There is no need to manually call
30 // Arm() on a Watcher using this policy.
31 //
32 // This provides a reasonable approximation of edge-triggered behavior,
33 // mitigating (but not completely eliminating) the potential for redundant
34 // notifications.
35 //
36 // For perfect edge-triggered behavior, use MANUAL policy and manually Arm()
37 // the Watcher as soon as it becomes possible to do so again.
38 AUTOMATIC,
39
40 // The Watcher is never armed automatically. Arm() must be called manually
41 // before any non-cancellation notification can be dispatched to the
42 // ReadyCallback. Immediately before the ReadyCallback is invoked, the
43 // Watcher is disarmed again and will require another manual call to Arm()
44 // before the next notification can fire.
45 MANUAL,
46 };
47
26 // A callback to be called any time a watched handle changes state in some 48 // A callback to be called any time a watched handle changes state in some
27 // interesting way. The |result| argument indicates one of the following 49 // interesting way. The |result| argument indicates one of the following
28 // conditions depending on its value: 50 // conditions depending on its value:
29 // 51 //
30 // |MOJO_RESULT_OK|: One or more of the signals being watched is satisfied. 52 // |MOJO_RESULT_OK|: One or more of the signals being watched is satisfied.
31 // 53 //
32 // |MOJO_RESULT_FAILED_PRECONDITION|: None of the signals being watched can 54 // |MOJO_RESULT_FAILED_PRECONDITION|: None of the signals being watched can
33 // ever be satisfied again. 55 // ever be satisfied again.
34 // 56 //
35 // |MOJO_RESULT_CANCELLED|: The handle has been closed and the watch has 57 // |MOJO_RESULT_CANCELLED|: The handle has been closed and the watch has
36 // been cancelled implicitly. 58 // been cancelled implicitly.
37 using ReadyCallback = base::Callback<void(MojoResult result)>; 59 using ReadyCallback = base::Callback<void(MojoResult result)>;
38 60
39 Watcher(const tracked_objects::Location& from_here, 61 Watcher(const tracked_objects::Location& from_here,
62 ArmingPolicy arming_policy,
40 scoped_refptr<base::SingleThreadTaskRunner> runner = 63 scoped_refptr<base::SingleThreadTaskRunner> runner =
41 base::ThreadTaskRunnerHandle::Get()); 64 base::ThreadTaskRunnerHandle::Get());
42 65
43 // NOTE: This destructor automatically calls |Cancel()| if the Watcher is 66 // NOTE: This destructor automatically calls |Cancel()| if the Watcher is
44 // still active. 67 // still active.
45 ~Watcher(); 68 ~Watcher();
46 69
47 // Indicates if the Watcher is currently watching a handle. 70 // Indicates if the Watcher is currently watching a handle.
48 bool IsWatching() const; 71 bool IsWatching() const;
49 72
50 // Starts watching |handle|. A Watcher may only watch one handle at a time, 73 // Starts watching |handle|. A Watcher may only watch one handle at a time,
51 // but it is safe to call this more than once as long as the previous watch 74 // but it is safe to call this more than once as long as the previous watch
52 // has been cancelled (i.e. |is_watching()| returns |false|.) 75 // has been cancelled (i.e. |is_watching()| returns |false|.)
53 // 76 //
54 // If no signals in |signals| can ever be satisfied for |handle|, this returns 77 // If no signals in |signals| can ever be satisfied for |handle|, this returns
55 // |MOJO_RESULT_FAILED_PRECONDITION|. 78 // |MOJO_RESULT_FAILED_PRECONDITION|.
56 // 79 //
57 // If |handle| is not a valid watchable (message or data pipe) handle, this 80 // If |handle| is not a valid watchable (message or data pipe) handle, this
58 // returns |MOJO_RESULT_INVALID_ARGUMENT|. 81 // returns |MOJO_RESULT_INVALID_ARGUMENT|.
59 // 82 //
60 // Otherwise |MOJO_RESULT_OK| is returned and the handle will be watched until 83 // Otherwise |MOJO_RESULT_OK| is returned and the handle will be watched until
61 // closure or cancellation. 84 // closure or cancellation.
62 // 85 //
63 // Once the watch is started, |callback| may be called at any time on the 86 // Once the watch is started, |callback| may be called at any time on the
64 // current thread until |Cancel()| is called or the handle is closed. 87 // current thread until |Cancel()| is called or the handle is closed. Note
88 // that |callback| will only be called for results other than
89 // |MOJO_RESULT_CANCELLED| if the Watcher is currently armed. Use ArmingPolicy
90 // to configure how a Watcher is armed.
65 // 91 //
66 // Destroying the Watcher implicitly calls |Cancel()|. 92 // Destroying the Watcher implicitly calls |Cancel()|.
67 MojoResult Start(Handle handle, 93 MojoResult Start(Handle handle,
68 MojoHandleSignals signals, 94 MojoHandleSignals signals,
69 const ReadyCallback& callback); 95 const ReadyCallback& callback);
70 96
71 // Cancels the current watch. Once this returns, the callback previously 97 // Cancels the current watch. Once this returns, the ReadyCallback previously
72 // passed to |Start()| will never be called again for this Watcher. 98 // passed to |Start()| will never be called again for this Watcher.
73 void Cancel(); 99 void Cancel();
74 100
101 // Manually arm the watcher. See documentation for MojoArmWatcher() for
102 // result code details.
103 //
104 // This is only needed when using MANUAL ArmingPolicy (see above.)
105 MojoResult Arm();
106
107 // Manually arm the watcher, or post a task to invoke the ReadyCallback
108 // with the result of the failed arming attempt. This is meant as a convenient
109 // helper for a common usage of Arm(), and it ensures that the ReadyCallback
110 // will be invoked asynchronously again as soon as the Watcher's conditions
111 // are satisfied, assuming the Watcher isn't cancelled first.
112 //
113 // Unlike Arm() above, this can never fail.
114 void ArmOrNotify();
115
75 Handle handle() const { return handle_; } 116 Handle handle() const { return handle_; }
76 ReadyCallback ready_callback() const { return callback_; } 117 ReadyCallback ready_callback() const { return callback_; }
77 118
78 // Sets the tag used by the heap profiler. 119 // Sets the tag used by the heap profiler.
79 // |tag| must be a const string literal. 120 // |tag| must be a const string literal.
80 void set_heap_profiler_tag(const char* heap_profiler_tag) { 121 void set_heap_profiler_tag(const char* heap_profiler_tag) {
81 heap_profiler_tag_ = heap_profiler_tag; 122 heap_profiler_tag_ = heap_profiler_tag;
82 } 123 }
83 124
84 private: 125 private:
85 void OnHandleReady(MojoResult result); 126 void OnHandleReady(MojoResult result);
127 void OnHandleReadyFromAnyThread(MojoResult result,
128 MojoWatchNotificationFlags flags);
86 129
87 static void CallOnHandleReady(uintptr_t context, 130 static void CallOnHandleReady(uintptr_t context,
88 MojoResult result, 131 MojoResult result,
89 MojoHandleSignalsState signals_state, 132 MojoHandleSignalsState signals_state,
90 MojoWatchNotificationFlags flags); 133 MojoWatchNotificationFlags flags);
91 134
92 base::ThreadChecker thread_checker_; 135 base::ThreadChecker thread_checker_;
93 136
137 // The policy used to determine how this Watcher is armed.
138 const ArmingPolicy arming_policy_;
139
94 // The TaskRunner of this Watcher's owning thread. This field is safe to 140 // The TaskRunner of this Watcher's owning thread. This field is safe to
95 // access from any thread. 141 // access from any thread.
96 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 142 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
97 // Whether |task_runner_| is the same as base::ThreadTaskRunnerHandle::Get() 143 // Whether |task_runner_| is the same as base::ThreadTaskRunnerHandle::Get()
98 // for the thread. 144 // for the thread.
99 const bool is_default_task_runner_; 145 const bool is_default_task_runner_;
100 146
101 // A persistent weak reference to this Watcher which can be passed to the 147 // A persistent weak reference to this Watcher which can be passed to the
102 // Dispatcher any time this object should be signalled. Safe to access (but 148 // Dispatcher any time this object should be signalled. Safe to access (but
103 // not to dereference!) from any thread. 149 // not to dereference!) from any thread.
104 base::WeakPtr<Watcher> weak_self_; 150 base::WeakPtr<Watcher> weak_self_;
105 151
106 // Fields below must only be accessed on the Watcher's owning thread. 152 // Fields below must only be accessed on the Watcher's owning thread.
107 153
108 // The handle currently under watch. Not owned. 154 // The handle currently under watch. Not owned.
109 Handle handle_; 155 Handle handle_;
110 156
111 // The callback to call when the handle is signaled. 157 // The callback to call when the handle is signaled.
112 ReadyCallback callback_; 158 ReadyCallback callback_;
113 159
114 // Tag used to ID memory allocations that originated from notifications in 160 // Tag used to ID memory allocations that originated from notifications in
115 // this watcher. 161 // this watcher.
116 const char* heap_profiler_tag_ = nullptr; 162 const char* heap_profiler_tag_ = nullptr;
117 163
164 // If this address is non-null during Watcher destruction, the value this
165 // references is set to |true|.
166 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
167
118 base::WeakPtrFactory<Watcher> weak_factory_; 168 base::WeakPtrFactory<Watcher> weak_factory_;
119 169
120 DISALLOW_COPY_AND_ASSIGN(Watcher); 170 DISALLOW_COPY_AND_ASSIGN(Watcher);
121 }; 171 };
122 172
123 } // namespace mojo 173 } // namespace mojo
124 174
125 #endif // MOJO_PUBLIC_CPP_SYSTEM_WATCHER_H_ 175 #endif // MOJO_PUBLIC_CPP_SYSTEM_WATCHER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698