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

Side by Side Diff: components/timers/alarm_timer_unittest.cc

Issue 2398753003: Use FileDescriptorWatcher in AlarmTimer. (Closed)
Patch Set: fix build error Created 4 years, 2 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <sys/timerfd.h> 5 #include <sys/timerfd.h>
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/files/file_descriptor_watcher_posix.h"
11 #include "base/location.h" 12 #include "base/location.h"
12 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
13 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h" 16 #include "base/run_loop.h"
15 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
16 #include "base/threading/platform_thread.h" 18 #include "base/threading/platform_thread.h"
17 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
18 #include "base/time/time.h" 20 #include "base/time/time.h"
19 #include "components/timers/alarm_timer_chromeos.h" 21 #include "components/timers/alarm_timer_chromeos.h"
20 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
21 23
22 // Most of these tests have been lifted right out of timer_unittest.cc with only 24 // Most of these tests have been lifted right out of timer_unittest.cc with only
23 // cosmetic changes (like replacing calls to MessageLoop::current()->Run() with 25 // cosmetic changes (like replacing calls to MessageLoop::current()->Run() with
24 // a RunLoop). We want the AlarmTimer to be a drop-in replacement for the 26 // a RunLoop). We want the AlarmTimer to be a drop-in replacement for the
25 // regular Timer so it should pass the same tests as the Timer class. 27 // regular Timer so it should pass the same tests as the Timer class.
26 //
27 // The only new tests are the .*ConcurrentResetAndTimerFired tests, which test
28 // that race conditions that can come up in the AlarmTimer::Delegate are
29 // properly handled.
30 namespace timers { 28 namespace timers {
31 namespace { 29 namespace {
32 // The message loops on which each timer should be tested.
33 const base::MessageLoop::Type testing_message_loops[] = {
34 base::MessageLoop::TYPE_DEFAULT,
35 base::MessageLoop::TYPE_IO,
36 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
37 base::MessageLoop::TYPE_UI,
38 #endif
39 };
40
41 const int kNumTestingMessageLoops = arraysize(testing_message_loops);
42 const base::TimeDelta kTenMilliseconds = base::TimeDelta::FromMilliseconds(10); 30 const base::TimeDelta kTenMilliseconds = base::TimeDelta::FromMilliseconds(10);
43 31
44 class OneShotAlarmTimerTester { 32 class OneShotAlarmTimerTester {
45 public: 33 public:
46 OneShotAlarmTimerTester(bool* did_run, base::TimeDelta delay) 34 OneShotAlarmTimerTester(bool* did_run, base::TimeDelta delay)
47 : did_run_(did_run), 35 : did_run_(did_run),
48 delay_(delay), 36 delay_(delay),
49 timer_(new timers::OneShotAlarmTimer()) {} 37 timer_(new timers::OneShotAlarmTimer()) {}
50 void Start() { 38 void Start() {
51 timer_->Start(FROM_HERE, delay_, base::Bind(&OneShotAlarmTimerTester::Run, 39 timer_->Start(FROM_HERE, delay_, base::Bind(&OneShotAlarmTimerTester::Run,
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 DISALLOW_COPY_AND_ASSIGN(RepeatingAlarmTimerTester); 114 DISALLOW_COPY_AND_ASSIGN(RepeatingAlarmTimerTester);
127 }; 115 };
128 116
129 } // namespace 117 } // namespace
130 118
131 //----------------------------------------------------------------------------- 119 //-----------------------------------------------------------------------------
132 // Each test is run against each type of MessageLoop. That way we are sure 120 // Each test is run against each type of MessageLoop. That way we are sure
133 // that timers work properly in all configurations. 121 // that timers work properly in all configurations.
134 122
135 TEST(AlarmTimerTest, OneShotAlarmTimer) { 123 TEST(AlarmTimerTest, OneShotAlarmTimer) {
136 for (int i = 0; i < kNumTestingMessageLoops; i++) { 124 base::MessageLoopForIO loop;
137 base::MessageLoop loop(testing_message_loops[i]); 125 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
138 126
139 bool did_run = false; 127 bool did_run = false;
140 OneShotAlarmTimerTester f(&did_run, kTenMilliseconds); 128 OneShotAlarmTimerTester f(&did_run, kTenMilliseconds);
141 f.Start(); 129 f.Start();
142 130
143 base::RunLoop().Run(); 131 base::RunLoop().Run();
144 132
145 EXPECT_TRUE(did_run); 133 EXPECT_TRUE(did_run);
146 }
147 } 134 }
148 135
149 TEST(AlarmTimerTest, OneShotAlarmTimer_Cancel) { 136 TEST(AlarmTimerTest, OneShotAlarmTimer_Cancel) {
150 for (int i = 0; i < kNumTestingMessageLoops; i++) { 137 base::MessageLoopForIO loop;
151 base::MessageLoop loop(testing_message_loops[i]); 138 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
152 139
153 bool did_run_a = false; 140 bool did_run_a = false;
154 OneShotAlarmTimerTester* a = 141 OneShotAlarmTimerTester* a =
155 new OneShotAlarmTimerTester(&did_run_a, kTenMilliseconds); 142 new OneShotAlarmTimerTester(&did_run_a, kTenMilliseconds);
156 143
157 // This should run before the timer expires. 144 // This should run before the timer expires.
158 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a); 145 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
159 146
160 // Now start the timer. 147 // Now start the timer.
161 a->Start(); 148 a->Start();
162 149
163 bool did_run_b = false; 150 bool did_run_b = false;
164 OneShotAlarmTimerTester b(&did_run_b, kTenMilliseconds); 151 OneShotAlarmTimerTester b(&did_run_b, kTenMilliseconds);
165 b.Start(); 152 b.Start();
166 153
167 base::RunLoop().Run(); 154 base::RunLoop().Run();
168 155
169 EXPECT_FALSE(did_run_a); 156 EXPECT_FALSE(did_run_a);
170 EXPECT_TRUE(did_run_b); 157 EXPECT_TRUE(did_run_b);
171 }
172 } 158 }
173 159
174 // If underlying timer does not handle this properly, we will crash or fail 160 // If underlying timer does not handle this properly, we will crash or fail
175 // in full page heap environment. 161 // in full page heap environment.
176 TEST(AlarmTimerTest, OneShotSelfDeletingAlarmTimer) { 162 TEST(AlarmTimerTest, OneShotSelfDeletingAlarmTimer) {
177 for (int i = 0; i < kNumTestingMessageLoops; i++) { 163 base::MessageLoopForIO loop;
178 base::MessageLoop loop(testing_message_loops[i]); 164 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
179 165
180 bool did_run = false; 166 bool did_run = false;
181 OneShotSelfDeletingAlarmTimerTester f(&did_run, kTenMilliseconds); 167 OneShotSelfDeletingAlarmTimerTester f(&did_run, kTenMilliseconds);
182 f.Start(); 168 f.Start();
183 169
184 base::RunLoop().Run(); 170 base::RunLoop().Run();
185 171
186 EXPECT_TRUE(did_run); 172 EXPECT_TRUE(did_run);
187 }
188 } 173 }
189 174
190 TEST(AlarmTimerTest, RepeatingAlarmTimer) { 175 TEST(AlarmTimerTest, RepeatingAlarmTimer) {
191 for (int i = 0; i < kNumTestingMessageLoops; i++) { 176 base::MessageLoopForIO loop;
192 base::MessageLoop loop(testing_message_loops[i]); 177 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
193 178
194 bool did_run = false; 179 bool did_run = false;
195 RepeatingAlarmTimerTester f(&did_run, kTenMilliseconds); 180 RepeatingAlarmTimerTester f(&did_run, kTenMilliseconds);
196 f.Start(); 181 f.Start();
197 182
198 base::RunLoop().Run(); 183 base::RunLoop().Run();
199 184
200 EXPECT_TRUE(did_run); 185 EXPECT_TRUE(did_run);
201 }
202 } 186 }
203 187
204 TEST(AlarmTimerTest, RepeatingAlarmTimer_Cancel) { 188 TEST(AlarmTimerTest, RepeatingAlarmTimer_Cancel) {
205 for (int i = 0; i < kNumTestingMessageLoops; i++) { 189 base::MessageLoopForIO loop;
206 base::MessageLoop loop(testing_message_loops[i]); 190 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
207 191
208 bool did_run_a = false; 192 bool did_run_a = false;
209 RepeatingAlarmTimerTester* a = 193 RepeatingAlarmTimerTester* a =
210 new RepeatingAlarmTimerTester(&did_run_a, kTenMilliseconds); 194 new RepeatingAlarmTimerTester(&did_run_a, kTenMilliseconds);
211 195
212 // This should run before the timer expires. 196 // This should run before the timer expires.
213 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a); 197 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
214 198
215 // Now start the timer. 199 // Now start the timer.
216 a->Start(); 200 a->Start();
217 201
218 bool did_run_b = false; 202 bool did_run_b = false;
219 RepeatingAlarmTimerTester b(&did_run_b, kTenMilliseconds); 203 RepeatingAlarmTimerTester b(&did_run_b, kTenMilliseconds);
220 b.Start(); 204 b.Start();
221 205
222 base::RunLoop().Run(); 206 base::RunLoop().Run();
223 207
224 EXPECT_FALSE(did_run_a); 208 EXPECT_FALSE(did_run_a);
225 EXPECT_TRUE(did_run_b); 209 EXPECT_TRUE(did_run_b);
226 }
227 } 210 }
228 211
229 TEST(AlarmTimerTest, RepeatingAlarmTimerZeroDelay) { 212 TEST(AlarmTimerTest, RepeatingAlarmTimerZeroDelay) {
230 for (int i = 0; i < kNumTestingMessageLoops; i++) { 213 base::MessageLoopForIO loop;
231 base::MessageLoop loop(testing_message_loops[i]); 214 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
232 215
233 bool did_run = false; 216 bool did_run = false;
234 RepeatingAlarmTimerTester f(&did_run, base::TimeDelta()); 217 RepeatingAlarmTimerTester f(&did_run, base::TimeDelta());
235 f.Start(); 218 f.Start();
236 219
237 base::RunLoop().Run(); 220 base::RunLoop().Run();
238 221
239 EXPECT_TRUE(did_run); 222 EXPECT_TRUE(did_run);
240 }
241 } 223 }
242 224
243 TEST(AlarmTimerTest, RepeatingAlarmTimerZeroDelay_Cancel) { 225 TEST(AlarmTimerTest, RepeatingAlarmTimerZeroDelay_Cancel) {
244 for (int i = 0; i < kNumTestingMessageLoops; i++) { 226 base::MessageLoopForIO loop;
245 base::MessageLoop loop(testing_message_loops[i]); 227 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
246 228
247 bool did_run_a = false; 229 bool did_run_a = false;
248 RepeatingAlarmTimerTester* a = 230 RepeatingAlarmTimerTester* a =
249 new RepeatingAlarmTimerTester(&did_run_a, base::TimeDelta()); 231 new RepeatingAlarmTimerTester(&did_run_a, base::TimeDelta());
250 232
251 // This should run before the timer expires. 233 // This should run before the timer expires.
252 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a); 234 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
253 235
254 // Now start the timer. 236 // Now start the timer.
255 a->Start(); 237 a->Start();
256 238
257 bool did_run_b = false; 239 bool did_run_b = false;
258 RepeatingAlarmTimerTester b(&did_run_b, base::TimeDelta()); 240 RepeatingAlarmTimerTester b(&did_run_b, base::TimeDelta());
259 b.Start(); 241 b.Start();
260 242
261 base::RunLoop().Run(); 243 base::RunLoop().Run();
262 244
263 EXPECT_FALSE(did_run_a); 245 EXPECT_FALSE(did_run_a);
264 EXPECT_TRUE(did_run_b); 246 EXPECT_TRUE(did_run_b);
265 }
266 } 247 }
267 248
268 TEST(AlarmTimerTest, MessageLoopShutdown) { 249 TEST(AlarmTimerTest, MessageLoopShutdown) {
269 // This test is designed to verify that shutdown of the 250 // This test is designed to verify that shutdown of the
270 // message loop does not cause crashes if there were pending 251 // message loop does not cause crashes if there were pending
271 // timers not yet fired. It may only trigger exceptions 252 // timers not yet fired. It may only trigger exceptions
272 // if debug heap checking is enabled. 253 // if debug heap checking is enabled.
273 bool did_run = false; 254 bool did_run = false;
274 { 255 {
256 auto loop = base::MakeUnique<base::MessageLoopForIO>();
257 auto file_descriptor_watcher =
258 base::MakeUnique<base::FileDescriptorWatcher>(loop.get());
275 OneShotAlarmTimerTester a(&did_run, kTenMilliseconds); 259 OneShotAlarmTimerTester a(&did_run, kTenMilliseconds);
276 OneShotAlarmTimerTester b(&did_run, kTenMilliseconds); 260 OneShotAlarmTimerTester b(&did_run, kTenMilliseconds);
277 OneShotAlarmTimerTester c(&did_run, kTenMilliseconds); 261 OneShotAlarmTimerTester c(&did_run, kTenMilliseconds);
278 OneShotAlarmTimerTester d(&did_run, kTenMilliseconds); 262 OneShotAlarmTimerTester d(&did_run, kTenMilliseconds);
279 { 263
280 base::MessageLoop loop; 264 a.Start();
281 a.Start(); 265 b.Start();
282 b.Start(); 266
283 } // MessageLoop destructs by falling out of scope. 267 // MessageLoop and FileDescriptorWatcher destruct.
284 } // OneShotTimers destruct. SHOULD NOT CRASH, of course. 268 file_descriptor_watcher.reset();
269 loop.reset();
270 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
285 271
286 EXPECT_FALSE(did_run); 272 EXPECT_FALSE(did_run);
287 } 273 }
288 274
289 TEST(AlarmTimerTest, NonRepeatIsRunning) { 275 TEST(AlarmTimerTest, NonRepeatIsRunning) {
290 { 276 {
291 base::MessageLoop loop; 277 base::MessageLoopForIO loop;
278 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
292 timers::OneShotAlarmTimer timer; 279 timers::OneShotAlarmTimer timer;
293 EXPECT_FALSE(timer.IsRunning()); 280 EXPECT_FALSE(timer.IsRunning());
294 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), 281 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
295 base::Bind(&base::DoNothing)); 282 base::Bind(&base::DoNothing));
296 EXPECT_TRUE(timer.IsRunning()); 283 EXPECT_TRUE(timer.IsRunning());
297 timer.Stop(); 284 timer.Stop();
298 EXPECT_FALSE(timer.IsRunning()); 285 EXPECT_FALSE(timer.IsRunning());
299 EXPECT_TRUE(timer.user_task().is_null()); 286 EXPECT_TRUE(timer.user_task().is_null());
300 } 287 }
301 288
302 { 289 {
290 base::MessageLoopForIO loop;
291 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
303 timers::SimpleAlarmTimer timer; 292 timers::SimpleAlarmTimer timer;
304 base::MessageLoop loop;
305 EXPECT_FALSE(timer.IsRunning()); 293 EXPECT_FALSE(timer.IsRunning());
306 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), 294 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
307 base::Bind(&base::DoNothing)); 295 base::Bind(&base::DoNothing));
308 EXPECT_TRUE(timer.IsRunning()); 296 EXPECT_TRUE(timer.IsRunning());
309 timer.Stop(); 297 timer.Stop();
310 EXPECT_FALSE(timer.IsRunning()); 298 EXPECT_FALSE(timer.IsRunning());
311 ASSERT_FALSE(timer.user_task().is_null()); 299 ASSERT_FALSE(timer.user_task().is_null());
312 timer.Reset(); 300 timer.Reset();
313 EXPECT_TRUE(timer.IsRunning()); 301 EXPECT_TRUE(timer.IsRunning());
314 } 302 }
315 } 303 }
316 304
317 TEST(AlarmTimerTest, NonRepeatMessageLoopDeath) { 305 TEST(AlarmTimerTest, RetainRepeatIsRunning) {
318 timers::OneShotAlarmTimer timer; 306 base::MessageLoopForIO loop;
319 { 307 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
320 base::MessageLoop loop; 308 timers::RepeatingAlarmTimer timer;
321 EXPECT_FALSE(timer.IsRunning());
322 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
323 base::Bind(&base::DoNothing));
324 EXPECT_TRUE(timer.IsRunning());
325 }
326 EXPECT_FALSE(timer.IsRunning()); 309 EXPECT_FALSE(timer.IsRunning());
327 EXPECT_TRUE(timer.user_task().is_null()); 310 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
328 } 311 base::Bind(&base::DoNothing));
329 312 EXPECT_TRUE(timer.IsRunning());
330 TEST(AlarmTimerTest, RetainRepeatIsRunning) {
331 base::MessageLoop loop;
332 timers::RepeatingAlarmTimer timer(FROM_HERE, base::TimeDelta::FromDays(1),
333 base::Bind(&base::DoNothing));
334 EXPECT_FALSE(timer.IsRunning());
335 timer.Reset(); 313 timer.Reset();
336 EXPECT_TRUE(timer.IsRunning()); 314 EXPECT_TRUE(timer.IsRunning());
337 timer.Stop(); 315 timer.Stop();
338 EXPECT_FALSE(timer.IsRunning()); 316 EXPECT_FALSE(timer.IsRunning());
339 timer.Reset(); 317 timer.Reset();
340 EXPECT_TRUE(timer.IsRunning()); 318 EXPECT_TRUE(timer.IsRunning());
341 } 319 }
342 320
343 TEST(AlarmTimerTest, RetainNonRepeatIsRunning) { 321 TEST(AlarmTimerTest, RetainNonRepeatIsRunning) {
344 base::MessageLoop loop; 322 base::MessageLoopForIO loop;
345 timers::SimpleAlarmTimer timer(FROM_HERE, base::TimeDelta::FromDays(1), 323 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
346 base::Bind(&base::DoNothing)); 324 timers::SimpleAlarmTimer timer;
347 EXPECT_FALSE(timer.IsRunning()); 325 EXPECT_FALSE(timer.IsRunning());
326 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
327 base::Bind(&base::DoNothing));
328 EXPECT_TRUE(timer.IsRunning());
348 timer.Reset(); 329 timer.Reset();
349 EXPECT_TRUE(timer.IsRunning()); 330 EXPECT_TRUE(timer.IsRunning());
350 timer.Stop(); 331 timer.Stop();
351 EXPECT_FALSE(timer.IsRunning()); 332 EXPECT_FALSE(timer.IsRunning());
352 timer.Reset(); 333 timer.Reset();
353 EXPECT_TRUE(timer.IsRunning()); 334 EXPECT_TRUE(timer.IsRunning());
354 } 335 }
355 336
356 namespace { 337 namespace {
357 338
(...skipping 11 matching lines...) Expand all
369 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 350 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
370 } 351 }
371 352
372 void SetCallbackHappened2() { 353 void SetCallbackHappened2() {
373 g_callback_happened2 = true; 354 g_callback_happened2 = true;
374 base::ThreadTaskRunnerHandle::Get()->PostTask( 355 base::ThreadTaskRunnerHandle::Get()->PostTask(
375 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 356 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
376 } 357 }
377 358
378 TEST(AlarmTimerTest, ContinuationStopStart) { 359 TEST(AlarmTimerTest, ContinuationStopStart) {
379 { 360 ClearAllCallbackHappened();
380 ClearAllCallbackHappened(); 361 base::MessageLoopForIO loop;
381 base::MessageLoop loop; 362 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
382 timers::OneShotAlarmTimer timer; 363 timers::OneShotAlarmTimer timer;
383 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10), 364 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10),
384 base::Bind(&SetCallbackHappened1)); 365 base::Bind(&SetCallbackHappened1));
385 timer.Stop(); 366 timer.Stop();
386 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(40), 367 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(40),
387 base::Bind(&SetCallbackHappened2)); 368 base::Bind(&SetCallbackHappened2));
388 base::RunLoop().Run(); 369 base::RunLoop().Run();
389 EXPECT_FALSE(g_callback_happened1); 370 EXPECT_FALSE(g_callback_happened1);
390 EXPECT_TRUE(g_callback_happened2); 371 EXPECT_TRUE(g_callback_happened2);
391 }
392 } 372 }
393 373
394 TEST(AlarmTimerTest, ContinuationReset) { 374 TEST(AlarmTimerTest, ContinuationReset) {
395 { 375 ClearAllCallbackHappened();
396 ClearAllCallbackHappened(); 376 base::MessageLoopForIO loop;
397 base::MessageLoop loop; 377 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
398 timers::OneShotAlarmTimer timer; 378 timers::OneShotAlarmTimer timer;
399 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10), 379 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10),
400 base::Bind(&SetCallbackHappened1)); 380 base::Bind(&SetCallbackHappened1));
401 timer.Reset(); 381 timer.Reset();
402 // Since Reset happened before task ran, the user_task must not be cleared: 382 // Since Reset happened before task ran, the user_task must not be cleared:
403 ASSERT_FALSE(timer.user_task().is_null()); 383 ASSERT_FALSE(timer.user_task().is_null());
404 base::RunLoop().Run(); 384 base::RunLoop().Run();
405 EXPECT_TRUE(g_callback_happened1); 385 EXPECT_TRUE(g_callback_happened1);
406 } 386 }
387
388 // Verify that no crash occurs if a timer is deleted while its callback is
389 // running.
390 TEST(AlarmTimerTest, DeleteTimerWhileCallbackIsRunning) {
391 base::MessageLoopForIO loop;
392 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
393 base::RunLoop run_loop;
394
395 // Will be deleted by the callback.
396 timers::OneShotAlarmTimer* timer = new timers::OneShotAlarmTimer;
397
398 timer->Start(
399 FROM_HERE, base::TimeDelta::FromMilliseconds(10),
400 base::Bind(
401 [](timers::OneShotAlarmTimer* timer, base::RunLoop* run_loop) {
402 delete timer;
403 run_loop->Quit();
404 },
405 timer, &run_loop));
406 run_loop.Run();
407 }
408
409 // Verify that no crash occurs if a zero-delay timer is deleted while its
410 // callback is running.
411 TEST(AlarmTimerTest, DeleteTimerWhileCallbackIsRunningZeroDelay) {
412 base::MessageLoopForIO loop;
413 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
414 base::RunLoop run_loop;
415
416 // Will be deleted by the callback.
417 timers::OneShotAlarmTimer* timer = new timers::OneShotAlarmTimer;
418
419 timer->Start(
420 FROM_HERE, base::TimeDelta(),
421 base::Bind(
422 [](timers::OneShotAlarmTimer* timer, base::RunLoop* run_loop) {
423 delete timer;
424 run_loop->Quit();
425 },
426 timer, &run_loop));
427 run_loop.Run();
407 } 428 }
408 429
409 } // namespace 430 } // namespace
410
411 namespace {
412 void TimerRanCallback(bool* did_run) {
413 *did_run = true;
414
415 base::ThreadTaskRunnerHandle::Get()->PostTask(
416 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
417 }
418
419 bool IsAlarmTimerSupported() {
420 int fd = timerfd_create(CLOCK_REALTIME_ALARM, 0);
421
422 if (fd == -1) {
423 LOG(WARNING) << "CLOCK_REALTIME_ALARM is not supported on this system. "
424 << "Skipping test. Upgrade to at least linux version 3.11 to "
425 << "support this timer.";
426 return false;
427 }
428
429 close(fd);
430 return true;
431 }
432
433 TEST(AlarmTimerTest, OneShotTimerConcurrentResetAndTimerFired) {
434 // The "Linux ChromiumOS .*" bots are still running Ubuntu 12.04, which
435 // doesn't have a linux version high enough to support the AlarmTimer. Since
436 // this test depends on SetTimerFiredCallbackForTest(), which is specific to
437 // the AlarmTimer, we have to just skip the test to stop it from failing.
438 if (!IsAlarmTimerSupported())
439 return;
440
441 for (int i = 0; i < kNumTestingMessageLoops; i++) {
442 base::MessageLoop loop(testing_message_loops[i]);
443
444 timers::OneShotAlarmTimer timer;
445 bool did_run = false;
446
447 base::RunLoop run_loop;
448
449 timer.SetTimerFiredCallbackForTest(run_loop.QuitClosure());
450 timer.Start(FROM_HERE, kTenMilliseconds,
451 base::Bind(&TimerRanCallback, &did_run));
452
453 // Wait until the timer has fired and a task has been queue in the
454 // MessageLoop.
455 run_loop.Run();
456
457 // Now reset the timer. This is attempting to simulate the timer firing and
458 // being reset at the same time. The previously queued task should be
459 // removed.
460 timer.Reset();
461
462 base::RunLoop().RunUntilIdle();
463 EXPECT_FALSE(did_run);
464
465 // If the previous check failed, running the message loop again will hang
466 // the test so we only do it if the callback has not run yet.
467 if (!did_run) {
468 base::RunLoop().Run();
469 EXPECT_TRUE(did_run);
470 }
471 }
472 }
473
474 TEST(AlarmTimerTest, RepeatingTimerConcurrentResetAndTimerFired) {
475 // The "Linux ChromiumOS .*" bots are still running Ubuntu 12.04, which
476 // doesn't have a linux version high enough to support the AlarmTimer. Since
477 // this test depends on SetTimerFiredCallbackForTest(), which is specific to
478 // the AlarmTimer, we have to just skip the test to stop it from failing.
479 if (!IsAlarmTimerSupported())
480 return;
481
482 for (int i = 0; i < kNumTestingMessageLoops; i++) {
483 base::MessageLoop loop(testing_message_loops[i]);
484
485 timers::RepeatingAlarmTimer timer;
486 bool did_run = false;
487
488 base::RunLoop run_loop;
489
490 timer.SetTimerFiredCallbackForTest(run_loop.QuitClosure());
491 timer.Start(FROM_HERE, kTenMilliseconds,
492 base::Bind(&TimerRanCallback, &did_run));
493
494 // Wait until the timer has fired and a task has been queue in the
495 // MessageLoop.
496 run_loop.Run();
497
498 // Now reset the timer. This is attempting to simulate the timer firing and
499 // being reset at the same time. The previously queued task should be
500 // removed.
501 timer.Reset();
502
503 base::RunLoop().RunUntilIdle();
504 EXPECT_FALSE(did_run);
505
506 // If the previous check failed, running the message loop again will hang
507 // the test so we only do it if the callback has not run yet.
508 if (!did_run) {
509 base::RunLoop().Run();
510 EXPECT_TRUE(did_run);
511 }
512 }
513 }
514
515 } // namespace
516
517 } // namespace timers 431 } // namespace timers
OLDNEW
« components/timers/alarm_timer_chromeos.cc ('K') | « components/timers/alarm_timer_chromeos.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698