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

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

Issue 2394333002: Revert of Use FileDescriptorWatcher in AlarmTimer. (Closed)
Patch Set: 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
« no previous file with comments | « components/timers/alarm_timer_chromeos.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
12 #include "base/location.h" 11 #include "base/location.h"
13 #include "base/macros.h" 12 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h" 14 #include "base/run_loop.h"
17 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
18 #include "base/threading/platform_thread.h" 16 #include "base/threading/platform_thread.h"
19 #include "base/threading/thread_task_runner_handle.h" 17 #include "base/threading/thread_task_runner_handle.h"
20 #include "base/time/time.h" 18 #include "base/time/time.h"
21 #include "components/timers/alarm_timer_chromeos.h" 19 #include "components/timers/alarm_timer_chromeos.h"
22 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
23 21
24 // Most of these tests have been lifted right out of timer_unittest.cc with only 22 // Most of these tests have been lifted right out of timer_unittest.cc with only
25 // cosmetic changes (like replacing calls to MessageLoop::current()->Run() with 23 // cosmetic changes (like replacing calls to MessageLoop::current()->Run() with
26 // a RunLoop). We want the AlarmTimer to be a drop-in replacement for the 24 // a RunLoop). We want the AlarmTimer to be a drop-in replacement for the
27 // regular Timer so it should pass the same tests as the Timer class. 25 // 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.
28 namespace timers { 30 namespace timers {
29 namespace { 31 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);
30 const base::TimeDelta kTenMilliseconds = base::TimeDelta::FromMilliseconds(10); 42 const base::TimeDelta kTenMilliseconds = base::TimeDelta::FromMilliseconds(10);
31 43
32 class OneShotAlarmTimerTester { 44 class OneShotAlarmTimerTester {
33 public: 45 public:
34 OneShotAlarmTimerTester(bool* did_run, base::TimeDelta delay) 46 OneShotAlarmTimerTester(bool* did_run, base::TimeDelta delay)
35 : did_run_(did_run), 47 : did_run_(did_run),
36 delay_(delay), 48 delay_(delay),
37 timer_(new timers::OneShotAlarmTimer()) {} 49 timer_(new timers::OneShotAlarmTimer()) {}
38 void Start() { 50 void Start() {
39 timer_->Start(FROM_HERE, delay_, base::Bind(&OneShotAlarmTimerTester::Run, 51 timer_->Start(FROM_HERE, delay_, base::Bind(&OneShotAlarmTimerTester::Run,
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 DISALLOW_COPY_AND_ASSIGN(RepeatingAlarmTimerTester); 126 DISALLOW_COPY_AND_ASSIGN(RepeatingAlarmTimerTester);
115 }; 127 };
116 128
117 } // namespace 129 } // namespace
118 130
119 //----------------------------------------------------------------------------- 131 //-----------------------------------------------------------------------------
120 // Each test is run against each type of MessageLoop. That way we are sure 132 // Each test is run against each type of MessageLoop. That way we are sure
121 // that timers work properly in all configurations. 133 // that timers work properly in all configurations.
122 134
123 TEST(AlarmTimerTest, OneShotAlarmTimer) { 135 TEST(AlarmTimerTest, OneShotAlarmTimer) {
124 base::MessageLoopForIO loop; 136 for (int i = 0; i < kNumTestingMessageLoops; i++) {
125 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 137 base::MessageLoop loop(testing_message_loops[i]);
126 138
127 bool did_run = false; 139 bool did_run = false;
128 OneShotAlarmTimerTester f(&did_run, kTenMilliseconds); 140 OneShotAlarmTimerTester f(&did_run, kTenMilliseconds);
129 f.Start(); 141 f.Start();
130 142
131 base::RunLoop().Run(); 143 base::RunLoop().Run();
132 144
133 EXPECT_TRUE(did_run); 145 EXPECT_TRUE(did_run);
146 }
134 } 147 }
135 148
136 TEST(AlarmTimerTest, OneShotAlarmTimer_Cancel) { 149 TEST(AlarmTimerTest, OneShotAlarmTimer_Cancel) {
137 base::MessageLoopForIO loop; 150 for (int i = 0; i < kNumTestingMessageLoops; i++) {
138 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 151 base::MessageLoop loop(testing_message_loops[i]);
139 152
140 bool did_run_a = false; 153 bool did_run_a = false;
141 OneShotAlarmTimerTester* a = 154 OneShotAlarmTimerTester* a =
142 new OneShotAlarmTimerTester(&did_run_a, kTenMilliseconds); 155 new OneShotAlarmTimerTester(&did_run_a, kTenMilliseconds);
143 156
144 // This should run before the timer expires. 157 // This should run before the timer expires.
145 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a); 158 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
146 159
147 // Now start the timer. 160 // Now start the timer.
148 a->Start(); 161 a->Start();
149 162
150 bool did_run_b = false; 163 bool did_run_b = false;
151 OneShotAlarmTimerTester b(&did_run_b, kTenMilliseconds); 164 OneShotAlarmTimerTester b(&did_run_b, kTenMilliseconds);
152 b.Start(); 165 b.Start();
153 166
154 base::RunLoop().Run(); 167 base::RunLoop().Run();
155 168
156 EXPECT_FALSE(did_run_a); 169 EXPECT_FALSE(did_run_a);
157 EXPECT_TRUE(did_run_b); 170 EXPECT_TRUE(did_run_b);
171 }
158 } 172 }
159 173
160 // If underlying timer does not handle this properly, we will crash or fail 174 // If underlying timer does not handle this properly, we will crash or fail
161 // in full page heap environment. 175 // in full page heap environment.
162 TEST(AlarmTimerTest, OneShotSelfDeletingAlarmTimer) { 176 TEST(AlarmTimerTest, OneShotSelfDeletingAlarmTimer) {
163 base::MessageLoopForIO loop; 177 for (int i = 0; i < kNumTestingMessageLoops; i++) {
164 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 178 base::MessageLoop loop(testing_message_loops[i]);
165 179
166 bool did_run = false; 180 bool did_run = false;
167 OneShotSelfDeletingAlarmTimerTester f(&did_run, kTenMilliseconds); 181 OneShotSelfDeletingAlarmTimerTester f(&did_run, kTenMilliseconds);
168 f.Start(); 182 f.Start();
169 183
170 base::RunLoop().Run(); 184 base::RunLoop().Run();
171 185
172 EXPECT_TRUE(did_run); 186 EXPECT_TRUE(did_run);
187 }
173 } 188 }
174 189
175 TEST(AlarmTimerTest, RepeatingAlarmTimer) { 190 TEST(AlarmTimerTest, RepeatingAlarmTimer) {
176 base::MessageLoopForIO loop; 191 for (int i = 0; i < kNumTestingMessageLoops; i++) {
177 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 192 base::MessageLoop loop(testing_message_loops[i]);
178 193
179 bool did_run = false; 194 bool did_run = false;
180 RepeatingAlarmTimerTester f(&did_run, kTenMilliseconds); 195 RepeatingAlarmTimerTester f(&did_run, kTenMilliseconds);
181 f.Start(); 196 f.Start();
182 197
183 base::RunLoop().Run(); 198 base::RunLoop().Run();
184 199
185 EXPECT_TRUE(did_run); 200 EXPECT_TRUE(did_run);
201 }
186 } 202 }
187 203
188 TEST(AlarmTimerTest, RepeatingAlarmTimer_Cancel) { 204 TEST(AlarmTimerTest, RepeatingAlarmTimer_Cancel) {
189 base::MessageLoopForIO loop; 205 for (int i = 0; i < kNumTestingMessageLoops; i++) {
190 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 206 base::MessageLoop loop(testing_message_loops[i]);
191 207
192 bool did_run_a = false; 208 bool did_run_a = false;
193 RepeatingAlarmTimerTester* a = 209 RepeatingAlarmTimerTester* a =
194 new RepeatingAlarmTimerTester(&did_run_a, kTenMilliseconds); 210 new RepeatingAlarmTimerTester(&did_run_a, kTenMilliseconds);
195 211
196 // This should run before the timer expires. 212 // This should run before the timer expires.
197 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a); 213 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
198 214
199 // Now start the timer. 215 // Now start the timer.
200 a->Start(); 216 a->Start();
201 217
202 bool did_run_b = false; 218 bool did_run_b = false;
203 RepeatingAlarmTimerTester b(&did_run_b, kTenMilliseconds); 219 RepeatingAlarmTimerTester b(&did_run_b, kTenMilliseconds);
204 b.Start(); 220 b.Start();
205 221
206 base::RunLoop().Run(); 222 base::RunLoop().Run();
207 223
208 EXPECT_FALSE(did_run_a); 224 EXPECT_FALSE(did_run_a);
209 EXPECT_TRUE(did_run_b); 225 EXPECT_TRUE(did_run_b);
226 }
210 } 227 }
211 228
212 TEST(AlarmTimerTest, RepeatingAlarmTimerZeroDelay) { 229 TEST(AlarmTimerTest, RepeatingAlarmTimerZeroDelay) {
213 base::MessageLoopForIO loop; 230 for (int i = 0; i < kNumTestingMessageLoops; i++) {
214 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 231 base::MessageLoop loop(testing_message_loops[i]);
215 232
216 bool did_run = false; 233 bool did_run = false;
217 RepeatingAlarmTimerTester f(&did_run, base::TimeDelta()); 234 RepeatingAlarmTimerTester f(&did_run, base::TimeDelta());
218 f.Start(); 235 f.Start();
219 236
220 base::RunLoop().Run(); 237 base::RunLoop().Run();
221 238
222 EXPECT_TRUE(did_run); 239 EXPECT_TRUE(did_run);
240 }
223 } 241 }
224 242
225 TEST(AlarmTimerTest, RepeatingAlarmTimerZeroDelay_Cancel) { 243 TEST(AlarmTimerTest, RepeatingAlarmTimerZeroDelay_Cancel) {
226 base::MessageLoopForIO loop; 244 for (int i = 0; i < kNumTestingMessageLoops; i++) {
227 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 245 base::MessageLoop loop(testing_message_loops[i]);
228 246
229 bool did_run_a = false; 247 bool did_run_a = false;
230 RepeatingAlarmTimerTester* a = 248 RepeatingAlarmTimerTester* a =
231 new RepeatingAlarmTimerTester(&did_run_a, base::TimeDelta()); 249 new RepeatingAlarmTimerTester(&did_run_a, base::TimeDelta());
232 250
233 // This should run before the timer expires. 251 // This should run before the timer expires.
234 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a); 252 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
235 253
236 // Now start the timer. 254 // Now start the timer.
237 a->Start(); 255 a->Start();
238 256
239 bool did_run_b = false; 257 bool did_run_b = false;
240 RepeatingAlarmTimerTester b(&did_run_b, base::TimeDelta()); 258 RepeatingAlarmTimerTester b(&did_run_b, base::TimeDelta());
241 b.Start(); 259 b.Start();
242 260
243 base::RunLoop().Run(); 261 base::RunLoop().Run();
244 262
245 EXPECT_FALSE(did_run_a); 263 EXPECT_FALSE(did_run_a);
246 EXPECT_TRUE(did_run_b); 264 EXPECT_TRUE(did_run_b);
265 }
247 } 266 }
248 267
249 TEST(AlarmTimerTest, MessageLoopShutdown) { 268 TEST(AlarmTimerTest, MessageLoopShutdown) {
250 // This test is designed to verify that shutdown of the 269 // This test is designed to verify that shutdown of the
251 // message loop does not cause crashes if there were pending 270 // message loop does not cause crashes if there were pending
252 // timers not yet fired. It may only trigger exceptions 271 // timers not yet fired. It may only trigger exceptions
253 // if debug heap checking is enabled. 272 // if debug heap checking is enabled.
254 bool did_run = false; 273 bool did_run = false;
255 { 274 {
256 auto loop = base::MakeUnique<base::MessageLoopForIO>();
257 auto file_descriptor_watcher =
258 base::MakeUnique<base::FileDescriptorWatcher>(loop.get());
259 OneShotAlarmTimerTester a(&did_run, kTenMilliseconds); 275 OneShotAlarmTimerTester a(&did_run, kTenMilliseconds);
260 OneShotAlarmTimerTester b(&did_run, kTenMilliseconds); 276 OneShotAlarmTimerTester b(&did_run, kTenMilliseconds);
261 OneShotAlarmTimerTester c(&did_run, kTenMilliseconds); 277 OneShotAlarmTimerTester c(&did_run, kTenMilliseconds);
262 OneShotAlarmTimerTester d(&did_run, kTenMilliseconds); 278 OneShotAlarmTimerTester d(&did_run, kTenMilliseconds);
263 279 {
264 a.Start(); 280 base::MessageLoop loop;
265 b.Start(); 281 a.Start();
266 282 b.Start();
267 // MessageLoop and FileDescriptorWatcher destruct. 283 } // MessageLoop destructs by falling out of scope.
268 file_descriptor_watcher.reset(); 284 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
269 loop.reset();
270 } // OneShotTimers destruct. SHOULD NOT CRASH, of course.
271 285
272 EXPECT_FALSE(did_run); 286 EXPECT_FALSE(did_run);
273 } 287 }
274 288
275 TEST(AlarmTimerTest, NonRepeatIsRunning) { 289 TEST(AlarmTimerTest, NonRepeatIsRunning) {
276 { 290 {
277 base::MessageLoopForIO loop; 291 base::MessageLoop loop;
278 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
279 timers::OneShotAlarmTimer timer; 292 timers::OneShotAlarmTimer timer;
280 EXPECT_FALSE(timer.IsRunning()); 293 EXPECT_FALSE(timer.IsRunning());
281 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), 294 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
282 base::Bind(&base::DoNothing)); 295 base::Bind(&base::DoNothing));
283 EXPECT_TRUE(timer.IsRunning()); 296 EXPECT_TRUE(timer.IsRunning());
284 timer.Stop(); 297 timer.Stop();
285 EXPECT_FALSE(timer.IsRunning()); 298 EXPECT_FALSE(timer.IsRunning());
286 EXPECT_TRUE(timer.user_task().is_null()); 299 EXPECT_TRUE(timer.user_task().is_null());
287 } 300 }
288 301
289 { 302 {
290 base::MessageLoopForIO loop;
291 base::FileDescriptorWatcher file_descriptor_watcher(&loop);
292 timers::SimpleAlarmTimer timer; 303 timers::SimpleAlarmTimer timer;
304 base::MessageLoop loop;
293 EXPECT_FALSE(timer.IsRunning()); 305 EXPECT_FALSE(timer.IsRunning());
294 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), 306 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
295 base::Bind(&base::DoNothing)); 307 base::Bind(&base::DoNothing));
296 EXPECT_TRUE(timer.IsRunning()); 308 EXPECT_TRUE(timer.IsRunning());
297 timer.Stop(); 309 timer.Stop();
298 EXPECT_FALSE(timer.IsRunning()); 310 EXPECT_FALSE(timer.IsRunning());
299 ASSERT_FALSE(timer.user_task().is_null()); 311 ASSERT_FALSE(timer.user_task().is_null());
300 timer.Reset(); 312 timer.Reset();
301 EXPECT_TRUE(timer.IsRunning()); 313 EXPECT_TRUE(timer.IsRunning());
302 } 314 }
303 } 315 }
304 316
317 TEST(AlarmTimerTest, NonRepeatMessageLoopDeath) {
318 timers::OneShotAlarmTimer timer;
319 {
320 base::MessageLoop loop;
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());
327 EXPECT_TRUE(timer.user_task().is_null());
328 }
329
305 TEST(AlarmTimerTest, RetainRepeatIsRunning) { 330 TEST(AlarmTimerTest, RetainRepeatIsRunning) {
306 base::MessageLoopForIO loop; 331 base::MessageLoop loop;
307 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 332 timers::RepeatingAlarmTimer timer(FROM_HERE, base::TimeDelta::FromDays(1),
308 timers::RepeatingAlarmTimer timer; 333 base::Bind(&base::DoNothing));
309 EXPECT_FALSE(timer.IsRunning()); 334 EXPECT_FALSE(timer.IsRunning());
310 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
311 base::Bind(&base::DoNothing));
312 EXPECT_TRUE(timer.IsRunning());
313 timer.Reset(); 335 timer.Reset();
314 EXPECT_TRUE(timer.IsRunning()); 336 EXPECT_TRUE(timer.IsRunning());
315 timer.Stop(); 337 timer.Stop();
316 EXPECT_FALSE(timer.IsRunning()); 338 EXPECT_FALSE(timer.IsRunning());
317 timer.Reset(); 339 timer.Reset();
318 EXPECT_TRUE(timer.IsRunning()); 340 EXPECT_TRUE(timer.IsRunning());
319 } 341 }
320 342
321 TEST(AlarmTimerTest, RetainNonRepeatIsRunning) { 343 TEST(AlarmTimerTest, RetainNonRepeatIsRunning) {
322 base::MessageLoopForIO loop; 344 base::MessageLoop loop;
323 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 345 timers::SimpleAlarmTimer timer(FROM_HERE, base::TimeDelta::FromDays(1),
324 timers::SimpleAlarmTimer timer; 346 base::Bind(&base::DoNothing));
325 EXPECT_FALSE(timer.IsRunning()); 347 EXPECT_FALSE(timer.IsRunning());
326 timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
327 base::Bind(&base::DoNothing));
328 EXPECT_TRUE(timer.IsRunning());
329 timer.Reset(); 348 timer.Reset();
330 EXPECT_TRUE(timer.IsRunning()); 349 EXPECT_TRUE(timer.IsRunning());
331 timer.Stop(); 350 timer.Stop();
332 EXPECT_FALSE(timer.IsRunning()); 351 EXPECT_FALSE(timer.IsRunning());
333 timer.Reset(); 352 timer.Reset();
334 EXPECT_TRUE(timer.IsRunning()); 353 EXPECT_TRUE(timer.IsRunning());
335 } 354 }
336 355
337 namespace { 356 namespace {
338 357
(...skipping 11 matching lines...) Expand all
350 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 369 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
351 } 370 }
352 371
353 void SetCallbackHappened2() { 372 void SetCallbackHappened2() {
354 g_callback_happened2 = true; 373 g_callback_happened2 = true;
355 base::ThreadTaskRunnerHandle::Get()->PostTask( 374 base::ThreadTaskRunnerHandle::Get()->PostTask(
356 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 375 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
357 } 376 }
358 377
359 TEST(AlarmTimerTest, ContinuationStopStart) { 378 TEST(AlarmTimerTest, ContinuationStopStart) {
360 ClearAllCallbackHappened(); 379 {
361 base::MessageLoopForIO loop; 380 ClearAllCallbackHappened();
362 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 381 base::MessageLoop loop;
363 timers::OneShotAlarmTimer timer; 382 timers::OneShotAlarmTimer timer;
364 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10), 383 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10),
365 base::Bind(&SetCallbackHappened1)); 384 base::Bind(&SetCallbackHappened1));
366 timer.Stop(); 385 timer.Stop();
367 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(40), 386 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(40),
368 base::Bind(&SetCallbackHappened2)); 387 base::Bind(&SetCallbackHappened2));
369 base::RunLoop().Run(); 388 base::RunLoop().Run();
370 EXPECT_FALSE(g_callback_happened1); 389 EXPECT_FALSE(g_callback_happened1);
371 EXPECT_TRUE(g_callback_happened2); 390 EXPECT_TRUE(g_callback_happened2);
391 }
372 } 392 }
373 393
374 TEST(AlarmTimerTest, ContinuationReset) { 394 TEST(AlarmTimerTest, ContinuationReset) {
375 ClearAllCallbackHappened(); 395 {
376 base::MessageLoopForIO loop; 396 ClearAllCallbackHappened();
377 base::FileDescriptorWatcher file_descriptor_watcher(&loop); 397 base::MessageLoop loop;
378 timers::OneShotAlarmTimer timer; 398 timers::OneShotAlarmTimer timer;
379 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10), 399 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10),
380 base::Bind(&SetCallbackHappened1)); 400 base::Bind(&SetCallbackHappened1));
381 timer.Reset(); 401 timer.Reset();
382 // Since Reset happened before task ran, the user_task must not be cleared: 402 // Since Reset happened before task ran, the user_task must not be cleared:
383 ASSERT_FALSE(timer.user_task().is_null()); 403 ASSERT_FALSE(timer.user_task().is_null());
384 base::RunLoop().Run(); 404 base::RunLoop().Run();
385 EXPECT_TRUE(g_callback_happened1); 405 EXPECT_TRUE(g_callback_happened1);
386 } 406 }
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();
428 } 407 }
429 408
430 } // namespace 409 } // 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
431 } // namespace timers 517 } // namespace timers
OLDNEW
« no previous file with comments | « components/timers/alarm_timer_chromeos.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698