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

Side by Side Diff: mojo/edk/system/watch_unittest.cc

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 #include <functional> 5 #include <functional>
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h" 10 #include "base/run_loop.h"
11 #include "base/single_thread_task_runner.h" 11 #include "base/single_thread_task_runner.h"
12 #include "base/threading/thread_task_runner_handle.h" 12 #include "base/threading/thread_task_runner_handle.h"
13 #include "mojo/edk/system/request_context.h" 13 #include "mojo/edk/system/request_context.h"
14 #include "mojo/edk/test/mojo_test_base.h" 14 #include "mojo/edk/test/mojo_test_base.h"
15 #include "mojo/public/c/system/functions.h" 15 #include "mojo/public/c/system/functions.h"
16 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 17
18 namespace mojo { 18 namespace mojo {
19 namespace edk { 19 namespace edk {
20 namespace { 20 namespace {
21 21
22 void IgnoreResult(uintptr_t context, 22 void IgnoreResult(uintptr_t context,
23 MojoResult result, 23 MojoResult result,
24 MojoHandleSignalsState signals, 24 MojoHandleSignalsState signals,
25 MojoWatchNotificationFlags flags) { 25 MojoWatchNotificationFlags flags) {
26 } 26 }
27 27
28 // A test helper class for watching a handle. The WatchHelper instance is used 28 // A test helper class for watching a handle. The WatchHelper instance is used
29 // as a watch context for a single watch callback. 29 // as a watcher context for a single watcher callback.
30 class WatchHelper { 30 class WatchHelper {
31 public: 31 public:
32 using Callback = 32 using Callback =
33 std::function<void(MojoResult result, MojoHandleSignalsState state)>; 33 std::function<void(MojoResult result, MojoHandleSignalsState state)>;
34 34
35 WatchHelper() : task_runner_(base::ThreadTaskRunnerHandle::Get()) {} 35 WatchHelper() : task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
36 ~WatchHelper() { 36 ~WatchHelper() {
37 CHECK(!watching_); 37 CHECK(!watching_);
38 } 38 }
39 39
40 void Watch(MojoHandle handle, 40 void Register(MojoHandle handle,
41 MojoHandleSignals signals, 41 MojoHandleSignals signals,
42 const Callback& callback) { 42 const Callback& callback) {
43 CHECK(!watching_); 43 CHECK(!watching_);
44 44
45 handle_ = handle; 45 handle_ = handle;
46 callback_ = callback; 46 callback_ = callback;
47 watching_ = true; 47 watching_ = true;
48 CHECK_EQ(MOJO_RESULT_OK, MojoWatch(handle_, signals, &WatchHelper::OnNotify, 48 CHECK_EQ(MOJO_RESULT_OK,
49 reinterpret_cast<uintptr_t>(this))); 49 MojoRegisterWatcher(handle_, signals, &WatchHelper::OnNotify,
50 reinterpret_cast<uintptr_t>(this)));
51 }
52
53 MojoResult Arm() {
54 return MojoArmWatcher(handle_, reinterpret_cast<uintptr_t>(this));
50 } 55 }
51 56
52 bool is_watching() const { return watching_; } 57 bool is_watching() const { return watching_; }
53 58
54 void Cancel() { 59 void Unregister() {
55 CHECK_EQ(MOJO_RESULT_OK, 60 CHECK_EQ(MOJO_RESULT_OK,
56 MojoCancelWatch(handle_, reinterpret_cast<uintptr_t>(this))); 61 MojoUnregisterWatcher(handle_, reinterpret_cast<uintptr_t>(this)));
57 CHECK(watching_); 62 CHECK(watching_);
58 watching_ = false; 63 watching_ = false;
59 } 64 }
60 65
61 private: 66 private:
62 static void OnNotify(uintptr_t context, 67 static void OnNotify(uintptr_t context,
63 MojoResult result, 68 MojoResult result,
64 MojoHandleSignalsState state, 69 MojoHandleSignalsState state,
65 MojoWatchNotificationFlags flags) { 70 MojoWatchNotificationFlags flags) {
66 WatchHelper* watcher = reinterpret_cast<WatchHelper*>(context); 71 WatchHelper* watcher = reinterpret_cast<WatchHelper*>(context);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 105
101 DISALLOW_COPY_AND_ASSIGN(WatchTest); 106 DISALLOW_COPY_AND_ASSIGN(WatchTest);
102 }; 107 };
103 108
104 TEST_F(WatchTest, NotifyBasic) { 109 TEST_F(WatchTest, NotifyBasic) {
105 MojoHandle a, b; 110 MojoHandle a, b;
106 CreateMessagePipe(&a, &b); 111 CreateMessagePipe(&a, &b);
107 112
108 base::RunLoop loop; 113 base::RunLoop loop;
109 WatchHelper b_watcher; 114 WatchHelper b_watcher;
110 b_watcher.Watch( 115 b_watcher.Register(
111 b, MOJO_HANDLE_SIGNAL_READABLE, 116 b, MOJO_HANDLE_SIGNAL_READABLE,
112 [&] (MojoResult result, MojoHandleSignalsState state) { 117 [&](MojoResult result, MojoHandleSignalsState state) {
113 EXPECT_EQ(MOJO_RESULT_OK, result); 118 EXPECT_EQ(MOJO_RESULT_OK, result);
114 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, 119 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
115 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); 120 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
116 EXPECT_TRUE(b_watcher.is_watching()); 121 EXPECT_TRUE(b_watcher.is_watching());
117 loop.Quit(); 122 loop.Quit();
118 }); 123 });
124 EXPECT_EQ(MOJO_RESULT_OK, b_watcher.Arm());
119 125
120 WriteMessage(a, "Hello!"); 126 WriteMessage(a, "Hello!");
121 loop.Run(); 127 loop.Run();
122 128
123 EXPECT_TRUE(b_watcher.is_watching()); 129 EXPECT_TRUE(b_watcher.is_watching());
124 b_watcher.Cancel(); 130 b_watcher.Unregister();
125 131
126 CloseHandle(a); 132 CloseHandle(a);
127 CloseHandle(b); 133 CloseHandle(b);
128 } 134 }
129 135
130 TEST_F(WatchTest, NotifyUnsatisfiable) { 136 TEST_F(WatchTest, NotifyUnsatisfiable) {
131 MojoHandle a, b; 137 MojoHandle a, b;
132 CreateMessagePipe(&a, &b); 138 CreateMessagePipe(&a, &b);
133 139
134 base::RunLoop loop; 140 base::RunLoop loop;
135 WatchHelper b_watcher; 141 WatchHelper b_watcher;
136 b_watcher.Watch( 142 b_watcher.Register(
137 b, MOJO_HANDLE_SIGNAL_READABLE, 143 b, MOJO_HANDLE_SIGNAL_READABLE,
138 [&] (MojoResult result, MojoHandleSignalsState state) { 144 [&](MojoResult result, MojoHandleSignalsState state) {
139 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); 145 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
140 EXPECT_EQ(0u, 146 EXPECT_EQ(0u,
141 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); 147 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
142 EXPECT_EQ(0u, 148 EXPECT_EQ(0u,
143 state.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE); 149 state.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
144 EXPECT_TRUE(b_watcher.is_watching()); 150 EXPECT_TRUE(b_watcher.is_watching());
145 loop.Quit(); 151 loop.Quit();
146 }); 152 });
153 EXPECT_EQ(MOJO_RESULT_OK, b_watcher.Arm());
147 154
148 CloseHandle(a); 155 CloseHandle(a);
149 loop.Run(); 156 loop.Run();
150 157
151 b_watcher.Cancel(); 158 b_watcher.Unregister();
152 159
153 CloseHandle(b); 160 CloseHandle(b);
154 } 161 }
155 162
156 TEST_F(WatchTest, NotifyCancellation) { 163 TEST_F(WatchTest, NotifyCancellation) {
157 MojoHandle a, b; 164 MojoHandle a, b;
158 CreateMessagePipe(&a, &b); 165 CreateMessagePipe(&a, &b);
159 166
160 base::RunLoop loop; 167 base::RunLoop loop;
161 WatchHelper b_watcher; 168 WatchHelper b_watcher;
162 b_watcher.Watch( 169 b_watcher.Register(b, MOJO_HANDLE_SIGNAL_READABLE,
163 b, MOJO_HANDLE_SIGNAL_READABLE, 170 [&](MojoResult result, MojoHandleSignalsState state) {
164 [&] (MojoResult result, MojoHandleSignalsState state) { 171 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
165 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); 172 EXPECT_EQ(0u, state.satisfied_signals);
166 EXPECT_EQ(0u, state.satisfied_signals); 173 EXPECT_EQ(0u, state.satisfiable_signals);
167 EXPECT_EQ(0u, state.satisfiable_signals); 174 EXPECT_FALSE(b_watcher.is_watching());
168 EXPECT_FALSE(b_watcher.is_watching()); 175 loop.Quit();
169 loop.Quit(); 176 });
170 });
171 177
172 CloseHandle(b); 178 CloseHandle(b);
173 loop.Run(); 179 loop.Run();
174 180
175 CloseHandle(a); 181 CloseHandle(a);
176 } 182 }
177 183
178 TEST_F(WatchTest, InvalidArguemnts) { 184 TEST_F(WatchTest, InvalidArguemnts) {
179 MojoHandle a, b; 185 MojoHandle a, b;
180 CreateMessagePipe(&a, &b); 186 CreateMessagePipe(&a, &b);
181 187
182 uintptr_t context = reinterpret_cast<uintptr_t>(this); 188 uintptr_t context = reinterpret_cast<uintptr_t>(this);
183 EXPECT_EQ(MOJO_RESULT_OK, MojoWatch(a, MOJO_HANDLE_SIGNAL_READABLE, 189 EXPECT_EQ(MOJO_RESULT_OK, MojoRegisterWatcher(a, MOJO_HANDLE_SIGNAL_READABLE,
184 &IgnoreResult, context)); 190 &IgnoreResult, context));
185 191
186 // Can't cancel a watch that doesn't exist. 192 // Can't arm a watcher that doesn't exist.
187 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoCancelWatch(a, ~context)); 193 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoArmWatcher(a, ~context));
188 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoCancelWatch(b, context)); 194 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoArmWatcher(b, context));
195
196 // Can't cancel a watcher that doesn't exist.
197 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoUnregisterWatcher(a, ~context));
198 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoUnregisterWatcher(b, context));
189 199
190 CloseHandle(a); 200 CloseHandle(a);
191 CloseHandle(b); 201 CloseHandle(b);
192 202
193 // Can't watch a handle that doesn't exist. 203 // Can't do anything with a handle that doesn't exist.
194 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 204 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
195 MojoWatch(a, MOJO_HANDLE_SIGNAL_READABLE, &IgnoreResult, context)); 205 MojoRegisterWatcher(a, MOJO_HANDLE_SIGNAL_READABLE, &IgnoreResult,
206 context));
196 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 207 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
197 MojoWatch(b, MOJO_HANDLE_SIGNAL_READABLE, &IgnoreResult, context)); 208 MojoRegisterWatcher(b, MOJO_HANDLE_SIGNAL_READABLE, &IgnoreResult,
209 context));
210 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoArmWatcher(a, context));
211 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoArmWatcher(b, context));
212 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoUnregisterWatcher(a, context));
213 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoUnregisterWatcher(b, context));
198 } 214 }
199 215
200 TEST_F(WatchTest, NoDuplicateContext) { 216 TEST_F(WatchTest, NoDuplicateContext) {
201 MojoHandle a, b; 217 MojoHandle a, b;
202 CreateMessagePipe(&a, &b); 218 CreateMessagePipe(&a, &b);
203 219
204 // Try to add the same watch twice; should fail. 220 // Try to add the same watcher twice; should fail.
205 uintptr_t context = reinterpret_cast<uintptr_t>(this); 221 uintptr_t context = reinterpret_cast<uintptr_t>(this);
206 EXPECT_EQ(MOJO_RESULT_OK, MojoWatch(a, MOJO_HANDLE_SIGNAL_READABLE, 222 EXPECT_EQ(MOJO_RESULT_OK, MojoRegisterWatcher(a, MOJO_HANDLE_SIGNAL_READABLE,
207 &IgnoreResult, context)); 223 &IgnoreResult, context));
208 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, 224 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
209 MojoWatch(a, MOJO_HANDLE_SIGNAL_READABLE, &IgnoreResult, context)); 225 MojoRegisterWatcher(a, MOJO_HANDLE_SIGNAL_READABLE, &IgnoreResult,
226 context));
210 227
211 // Cancel and add it again; should be OK. 228 // Cancel and add it again; should be OK.
212 EXPECT_EQ(MOJO_RESULT_OK, MojoCancelWatch(a, context)); 229 EXPECT_EQ(MOJO_RESULT_OK, MojoUnregisterWatcher(a, context));
213 EXPECT_EQ(MOJO_RESULT_OK, MojoWatch(a, MOJO_HANDLE_SIGNAL_READABLE, 230 EXPECT_EQ(MOJO_RESULT_OK, MojoRegisterWatcher(a, MOJO_HANDLE_SIGNAL_READABLE,
214 &IgnoreResult, context)); 231 &IgnoreResult, context));
215 232
216 CloseHandle(a); 233 CloseHandle(a);
217 CloseHandle(b); 234 CloseHandle(b);
218 } 235 }
219 236
220 TEST_F(WatchTest, MultipleWatches) { 237 TEST_F(WatchTest, MultipleWatches) {
221 MojoHandle a, b; 238 MojoHandle a, b;
222 CreateMessagePipe(&a, &b); 239 CreateMessagePipe(&a, &b);
223 240
224 // Add multiple watchers to |b| and see that they are both notified by a 241 // Add multiple watchers to |b| and see that they are both notified by a
225 // single write to |a|. 242 // single write to |a|.
226 base::RunLoop loop; 243 base::RunLoop loop;
227 int expected_notifications = 2; 244 int expected_notifications = 2;
228 auto on_readable = [&] (MojoResult result, MojoHandleSignalsState state) { 245 auto on_readable = [&] (MojoResult result, MojoHandleSignalsState state) {
229 EXPECT_EQ(MOJO_RESULT_OK, result); 246 EXPECT_EQ(MOJO_RESULT_OK, result);
230 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, 247 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
231 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); 248 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
232 EXPECT_GT(expected_notifications, 0); 249 EXPECT_GT(expected_notifications, 0);
233 if (--expected_notifications == 0) 250 if (--expected_notifications == 0)
234 loop.Quit(); 251 loop.Quit();
235 }; 252 };
253
236 WatchHelper watcher1; 254 WatchHelper watcher1;
255 watcher1.Register(b, MOJO_HANDLE_SIGNAL_READABLE, on_readable);
256 EXPECT_EQ(MOJO_RESULT_OK, watcher1.Arm());
257
237 WatchHelper watcher2; 258 WatchHelper watcher2;
238 watcher1.Watch(b, MOJO_HANDLE_SIGNAL_READABLE, on_readable); 259 watcher2.Register(b, MOJO_HANDLE_SIGNAL_READABLE, on_readable);
239 watcher2.Watch(b, MOJO_HANDLE_SIGNAL_READABLE, on_readable); 260 EXPECT_EQ(MOJO_RESULT_OK, watcher2.Arm());
240 261
241 WriteMessage(a, "Ping!"); 262 WriteMessage(a, "Ping!");
242 loop.Run(); 263 loop.Run();
243 264
244 watcher1.Cancel(); 265 watcher1.Unregister();
245 watcher2.Cancel(); 266 watcher2.Unregister();
246 267
247 CloseHandle(a); 268 CloseHandle(a);
248 CloseHandle(b); 269 CloseHandle(b);
249 } 270 }
250 271
251 TEST_F(WatchTest, WatchWhileSatisfied) { 272 TEST_F(WatchTest, ArmWhileSatisfied) {
252 MojoHandle a, b; 273 MojoHandle a, b;
253 CreateMessagePipe(&a, &b); 274 CreateMessagePipe(&a, &b);
254 275
255 // Write to |a| and then start watching |b|. The callback should be invoked 276 // Write to |a| while watching for |b| to become readable.
256 // synchronously.
257 WriteMessage(a, "hey");
258 bool signaled = false; 277 bool signaled = false;
259 WatchHelper b_watcher; 278 WatchHelper b_watcher;
260 base::RunLoop loop; 279 base::RunLoop loop;
261 b_watcher.Watch( 280 b_watcher.Register(
262 b, MOJO_HANDLE_SIGNAL_READABLE, 281 b, MOJO_HANDLE_SIGNAL_READABLE,
263 [&] (MojoResult result, MojoHandleSignalsState state) { 282 [&](MojoResult result, MojoHandleSignalsState state) {
264 EXPECT_EQ(MOJO_RESULT_OK, result); 283 EXPECT_EQ(MOJO_RESULT_OK, result);
265 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, 284 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
266 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); 285 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
267 signaled = true; 286 signaled = true;
268 loop.Quit(); 287 loop.Quit();
269 }); 288 });
289 EXPECT_EQ(MOJO_RESULT_OK, b_watcher.Arm());
290 WriteMessage(a, "hey");
270 loop.Run(); 291 loop.Run();
271 EXPECT_TRUE(signaled); 292 EXPECT_TRUE(signaled);
272 b_watcher.Cancel(); 293
294 // Now |b| is still readable, so arming should indicate as much.
295 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, b_watcher.Arm());
296 b_watcher.Unregister();
273 297
274 CloseHandle(a); 298 CloseHandle(a);
275 CloseHandle(b); 299 CloseHandle(b);
276 } 300 }
277 301
278 TEST_F(WatchTest, WatchWhileUnsatisfiable) { 302 TEST_F(WatchTest, WatchWhileUnsatisfiable) {
279 MojoHandle a, b; 303 MojoHandle a, b;
280 CreateMessagePipe(&a, &b); 304 CreateMessagePipe(&a, &b);
281 305
282 // Close |a| and then try to watch |b|. MojoWatch() should fail. 306 // Close |a| and then try to watch |b|. MojoRegisterWatcher() should fail.
283 CloseHandle(a); 307 CloseHandle(a);
284 uintptr_t context = reinterpret_cast<uintptr_t>(this); 308 uintptr_t context = reinterpret_cast<uintptr_t>(this);
285 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 309 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
286 MojoWatch(b, MOJO_HANDLE_SIGNAL_READABLE, &IgnoreResult, context)); 310 MojoRegisterWatcher(b, MOJO_HANDLE_SIGNAL_READABLE, &IgnoreResult,
311 context));
287 312
288 CloseHandle(b); 313 CloseHandle(b);
289 } 314 }
290 315
291 TEST_F(WatchTest, RespondFromCallback) { 316 TEST_F(WatchTest, RespondFromCallback) {
292 MojoHandle a, b; 317 MojoHandle a, b;
293 CreateMessagePipe(&a, &b); 318 CreateMessagePipe(&a, &b);
294 319
295 // Watch |a| and |b|. Write to |a|, then write to |b| from within the callback 320 // Watch |a| and |b|. Write to |a|, then write to |b| from within the callback
296 // which notifies it of the available message. 321 // which notifies it of the available message.
297 const std::string kTestMessage = "hello worlds."; 322 const std::string kTestMessage = "hello worlds.";
298 base::RunLoop loop; 323 base::RunLoop loop;
299 WatchHelper b_watcher; 324 WatchHelper b_watcher;
300 b_watcher.Watch( 325 b_watcher.Register(
301 b, MOJO_HANDLE_SIGNAL_READABLE, 326 b, MOJO_HANDLE_SIGNAL_READABLE,
302 [&] (MojoResult result, MojoHandleSignalsState state) { 327 [&](MojoResult result, MojoHandleSignalsState state) {
303 EXPECT_EQ(MOJO_RESULT_OK, result); 328 EXPECT_EQ(MOJO_RESULT_OK, result);
304 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, 329 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
305 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); 330 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
306 EXPECT_TRUE(b_watcher.is_watching()); 331 EXPECT_TRUE(b_watcher.is_watching());
307 332
308 // Echo a's message back to it. 333 // Echo a's message back to it.
309 WriteMessage(b, ReadMessage(b)); 334 WriteMessage(b, ReadMessage(b));
310 }); 335 });
336 EXPECT_EQ(MOJO_RESULT_OK, b_watcher.Arm());
311 337
312 WatchHelper a_watcher; 338 WatchHelper a_watcher;
313 a_watcher.Watch( 339 a_watcher.Register(
314 a, MOJO_HANDLE_SIGNAL_READABLE, 340 a, MOJO_HANDLE_SIGNAL_READABLE,
315 [&] (MojoResult result, MojoHandleSignalsState state) { 341 [&](MojoResult result, MojoHandleSignalsState state) {
316 EXPECT_EQ(MOJO_RESULT_OK, result); 342 EXPECT_EQ(MOJO_RESULT_OK, result);
317 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, 343 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
318 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); 344 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
319 EXPECT_TRUE(a_watcher.is_watching()); 345 EXPECT_TRUE(a_watcher.is_watching());
320 346
321 // Expect to receive back the message that was originally sent to |b|. 347 // Expect to receive back the message that was originally sent to |b|.
322 EXPECT_EQ(kTestMessage, ReadMessage(a)); 348 EXPECT_EQ(kTestMessage, ReadMessage(a));
323 349
324 loop.Quit(); 350 loop.Quit();
325 }); 351 });
352 EXPECT_EQ(MOJO_RESULT_OK, a_watcher.Arm());
326 353
327 WriteMessage(a, kTestMessage); 354 WriteMessage(a, kTestMessage);
328 loop.Run(); 355 loop.Run();
329 356
330 a_watcher.Cancel(); 357 a_watcher.Unregister();
331 b_watcher.Cancel(); 358 b_watcher.Unregister();
332 359
333 CloseHandle(a); 360 CloseHandle(a);
334 CloseHandle(b); 361 CloseHandle(b);
335 } 362 }
336 363
337 TEST_F(WatchTest, WatchDataPipeConsumer) { 364 TEST_F(WatchTest, WatchDataPipeConsumer) {
338 MojoHandle a, b; 365 MojoHandle a, b;
339 CreateDataPipe(&a, &b, 64); 366 CreateDataPipe(&a, &b, 64);
340 367
341 base::RunLoop loop; 368 base::RunLoop loop;
342 WatchHelper b_watcher; 369 WatchHelper b_watcher;
343 b_watcher.Watch( 370 b_watcher.Register(
344 b, MOJO_HANDLE_SIGNAL_READABLE, 371 b, MOJO_HANDLE_SIGNAL_READABLE,
345 [&] (MojoResult result, MojoHandleSignalsState state) { 372 [&](MojoResult result, MojoHandleSignalsState state) {
346 EXPECT_EQ(MOJO_RESULT_OK, result); 373 EXPECT_EQ(MOJO_RESULT_OK, result);
347 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, 374 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
348 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); 375 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
349 EXPECT_TRUE(b_watcher.is_watching()); 376 EXPECT_TRUE(b_watcher.is_watching());
350 loop.Quit(); 377 loop.Quit();
351 }); 378 });
379 EXPECT_EQ(MOJO_RESULT_OK, b_watcher.Arm());
352 380
353 WriteData(a, "Hello!"); 381 WriteData(a, "Hello!");
354 loop.Run(); 382 loop.Run();
355 383
356 EXPECT_TRUE(b_watcher.is_watching()); 384 EXPECT_TRUE(b_watcher.is_watching());
357 b_watcher.Cancel(); 385 b_watcher.Unregister();
358 386
359 CloseHandle(a); 387 CloseHandle(a);
360 CloseHandle(b); 388 CloseHandle(b);
361 } 389 }
362 390
363 TEST_F(WatchTest, WatchDataPipeProducer) { 391 TEST_F(WatchTest, WatchDataPipeProducer) {
364 MojoHandle a, b; 392 MojoHandle a, b;
365 CreateDataPipe(&a, &b, 8); 393 CreateDataPipe(&a, &b, 8);
366 394
367 // Fill the pipe to capacity so writes will block. 395 // Fill the pipe to capacity so writes will block.
368 WriteData(a, "xxxxxxxx"); 396 WriteData(a, "xxxxxxxx");
369 397
370 base::RunLoop loop; 398 base::RunLoop loop;
371 WatchHelper a_watcher; 399 WatchHelper a_watcher;
372 a_watcher.Watch( 400 a_watcher.Register(
373 a, MOJO_HANDLE_SIGNAL_WRITABLE, 401 a, MOJO_HANDLE_SIGNAL_WRITABLE,
374 [&] (MojoResult result, MojoHandleSignalsState state) { 402 [&](MojoResult result, MojoHandleSignalsState state) {
375 EXPECT_EQ(MOJO_RESULT_OK, result); 403 EXPECT_EQ(MOJO_RESULT_OK, result);
376 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, 404 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE,
377 state.satisfied_signals & MOJO_HANDLE_SIGNAL_WRITABLE); 405 state.satisfied_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
378 EXPECT_TRUE(a_watcher.is_watching()); 406 EXPECT_TRUE(a_watcher.is_watching());
379 loop.Quit(); 407 loop.Quit();
380 }); 408 });
409 EXPECT_EQ(MOJO_RESULT_OK, a_watcher.Arm());
381 410
382 EXPECT_EQ("xxxxxxxx", ReadData(b, 8)); 411 EXPECT_EQ("xxxxxxxx", ReadData(b, 8));
383 loop.Run(); 412 loop.Run();
384 413
385 EXPECT_TRUE(a_watcher.is_watching()); 414 EXPECT_TRUE(a_watcher.is_watching());
386 a_watcher.Cancel(); 415 a_watcher.Unregister();
387 416
388 CloseHandle(a); 417 CloseHandle(a);
389 CloseHandle(b); 418 CloseHandle(b);
390 } 419 }
391 420
392 TEST_F(WatchTest, WakeUpSelfWithinWatchCallback) { 421 TEST_F(WatchTest, WakeUpSelfWithinWatchCallback) {
393 MojoHandle a, b; 422 MojoHandle a, b;
394 CreateMessagePipe(&a, &b); 423 CreateMessagePipe(&a, &b);
395 424
396 int expected_notifications = 2; 425 int expected_notifications = 2;
397 base::RunLoop loop; 426 base::RunLoop loop;
398 WatchHelper b_watcher; 427 WatchHelper b_watcher;
399 b_watcher.Watch( 428 b_watcher.Register(
400 b, MOJO_HANDLE_SIGNAL_READABLE, 429 b, MOJO_HANDLE_SIGNAL_READABLE,
401 [&] (MojoResult result, MojoHandleSignalsState state) { 430 [&](MojoResult result, MojoHandleSignalsState state) {
402 EXPECT_EQ(MOJO_RESULT_OK, result); 431 EXPECT_EQ(MOJO_RESULT_OK, result);
403 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, 432 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE,
404 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); 433 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE);
405 EXPECT_TRUE(b_watcher.is_watching()); 434 EXPECT_TRUE(b_watcher.is_watching());
406 if (--expected_notifications == 0) { 435 if (--expected_notifications == 0) {
407 loop.Quit(); 436 loop.Quit();
408 } else { 437 } else {
438 // Read the message off the pipe and re-arm the watcher.
439 ReadMessage(b);
440 EXPECT_EQ(MOJO_RESULT_OK, b_watcher.Arm());
441
409 // Trigger b's watch again from within this callback. This should be 442 // Trigger b's watch again from within this callback. This should be
410 // safe to do. 443 // safe to do.
411 WriteMessage(a, "hey"); 444 WriteMessage(a, "hey");
412 } 445 }
413 }); 446 });
447 EXPECT_EQ(MOJO_RESULT_OK, b_watcher.Arm());
414 448
415 WriteMessage(a, "hey hey hey"); 449 WriteMessage(a, "hey hey hey");
416 loop.Run(); 450 loop.Run();
417 451
418 b_watcher.Cancel(); 452 b_watcher.Unregister();
419 453
420 CloseHandle(a); 454 CloseHandle(a);
421 CloseHandle(b); 455 CloseHandle(b);
422 } 456 }
423 457
424 TEST_F(WatchTest, NestedCancellation) { 458 TEST_F(WatchTest, NestedCancellation) {
425 // Verifies that cancellations in nested system request contexts preempt 459 // Verifies that cancellations in nested system request contexts preempt
426 // other notifications for the same watcher. This tests against the condition 460 // other notifications for the same watcher. This tests against the condition
427 // hit by http://crbug.com/622298. 461 // hit by http://crbug.com/622298.
428 462
429 MojoHandle a, b, c, d; 463 MojoHandle a, b, c, d;
430 CreateMessagePipe(&a, &b); 464 CreateMessagePipe(&a, &b);
431 CreateMessagePipe(&c, &d); 465 CreateMessagePipe(&c, &d);
432 466
433 base::RunLoop loop; 467 base::RunLoop loop;
434 bool a_watcher_run = false; 468 bool a_watcher_run = false;
435 WatchHelper a_watcher; 469 WatchHelper a_watcher;
436 a_watcher.Watch( 470 a_watcher.Register(a, MOJO_HANDLE_SIGNAL_READABLE,
437 a, MOJO_HANDLE_SIGNAL_READABLE, 471 [&](MojoResult result, MojoHandleSignalsState state) {
438 [&](MojoResult result, MojoHandleSignalsState state) { 472 a_watcher_run = true;
439 a_watcher_run = true; 473 });
440 });
441 474
442 WatchHelper c_watcher; 475 WatchHelper c_watcher;
443 c_watcher.Watch( 476 c_watcher.Register(c, MOJO_HANDLE_SIGNAL_READABLE,
444 c, MOJO_HANDLE_SIGNAL_READABLE, 477 [&](MojoResult result, MojoHandleSignalsState state) {
445 [&](MojoResult result, MojoHandleSignalsState state) { 478 // This will trigger a notification on |a_watcher| above
446 // This will trigger a notification on |a_watcher| above to be executed 479 // to be executed once this handler finishes running...
447 // once this handler finishes running... 480 CloseHandle(b);
448 CloseHandle(b);
449 481
450 // ...but this should prevent that notification from dispatching because 482 // ...but this should prevent that notification from
451 // |a_watcher| is now cancelled. 483 // dispatching because |a_watcher| is now cancelled.
452 a_watcher.Cancel(); 484 a_watcher.Unregister();
453 485
454 loop.Quit(); 486 loop.Quit();
455 }); 487 });
488 c_watcher.Arm();
456 489
457 { 490 {
458 // Force "system" notifications for the synchronous behavior required to 491 // Force "system" notifications for the synchronous behavior required to
459 // test this case. 492 // test this case.
460 mojo::edk::RequestContext request_context( 493 mojo::edk::RequestContext request_context(
461 mojo::edk::RequestContext::Source::SYSTEM); 494 mojo::edk::RequestContext::Source::SYSTEM);
462 495
463 // Trigger the |c_watcher| callback above. 496 // Trigger the |c_watcher| callback above.
464 CloseHandle(d); 497 CloseHandle(d);
465 } 498 }
466 499
467 loop.Run(); 500 loop.Run();
468 501
469 EXPECT_FALSE(a_watcher.is_watching()); 502 EXPECT_FALSE(a_watcher.is_watching());
470 EXPECT_FALSE(a_watcher_run); 503 EXPECT_FALSE(a_watcher_run);
471 504
472 c_watcher.Cancel(); 505 c_watcher.Unregister();
473 506
474 CloseHandle(a); 507 CloseHandle(a);
475 CloseHandle(c); 508 CloseHandle(c);
476 } 509 }
477 510
478 } // namespace 511 } // namespace
479 } // namespace edk 512 } // namespace edk
480 } // namespace mojo 513 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698