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

Side by Side Diff: base/threading/thread_unittest.cc

Issue 2791243002: Rewrite base::Bind into base::BindOnce on trivial cases in base (Closed)
Patch Set: rebase Created 3 years, 8 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 | « base/threading/thread_perftest.cc ('k') | base/threading/worker_pool_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/threading/thread.h" 5 #include "base/threading/thread.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <vector> 10 #include <vector>
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 options.stack_size = 2 * 3072 * sizeof(uintptr_t); 148 options.stack_size = 2 * 3072 * sizeof(uintptr_t);
149 #else 149 #else
150 options.stack_size = 3072 * sizeof(uintptr_t); 150 options.stack_size = 3072 * sizeof(uintptr_t);
151 #endif 151 #endif
152 EXPECT_TRUE(a.StartWithOptions(options)); 152 EXPECT_TRUE(a.StartWithOptions(options));
153 EXPECT_TRUE(a.message_loop()); 153 EXPECT_TRUE(a.message_loop());
154 EXPECT_TRUE(a.IsRunning()); 154 EXPECT_TRUE(a.IsRunning());
155 155
156 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, 156 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
157 base::WaitableEvent::InitialState::NOT_SIGNALED); 157 base::WaitableEvent::InitialState::NOT_SIGNALED);
158 a.task_runner()->PostTask(FROM_HERE, base::Bind(&base::WaitableEvent::Signal, 158 a.task_runner()->PostTask(
159 base::Unretained(&event))); 159 FROM_HERE,
160 base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event)));
160 event.Wait(); 161 event.Wait();
161 } 162 }
162 163
163 // Intentional test-only race for otherwise untestable code, won't fix. 164 // Intentional test-only race for otherwise untestable code, won't fix.
164 // https://crbug.com/634383 165 // https://crbug.com/634383
165 #if !defined(THREAD_SANITIZER) 166 #if !defined(THREAD_SANITIZER)
166 TEST_F(ThreadTest, StartWithOptions_NonJoinable) { 167 TEST_F(ThreadTest, StartWithOptions_NonJoinable) {
167 Thread* a = new Thread("StartNonJoinable"); 168 Thread* a = new Thread("StartNonJoinable");
168 // Non-joinable threads have to be leaked for now (see 169 // Non-joinable threads have to be leaked for now (see
169 // Thread::Options::joinable for details). 170 // Thread::Options::joinable for details).
(...skipping 11 matching lines...) Expand all
181 // satisfied and the real |is_running_| bit has to be checked. It could still 182 // satisfied and the real |is_running_| bit has to be checked. It could still
182 // be false if the message loop hasn't started for real in practice. This is 183 // be false if the message loop hasn't started for real in practice. This is
183 // only a requirement for this test because the non-joinable property forces 184 // only a requirement for this test because the non-joinable property forces
184 // it to use StopSoon() and not wait for a complete Stop(). 185 // it to use StopSoon() and not wait for a complete Stop().
185 EXPECT_TRUE(a->WaitUntilThreadStarted()); 186 EXPECT_TRUE(a->WaitUntilThreadStarted());
186 187
187 // Make the thread block until |block_event| is signaled. 188 // Make the thread block until |block_event| is signaled.
188 base::WaitableEvent block_event( 189 base::WaitableEvent block_event(
189 base::WaitableEvent::ResetPolicy::AUTOMATIC, 190 base::WaitableEvent::ResetPolicy::AUTOMATIC,
190 base::WaitableEvent::InitialState::NOT_SIGNALED); 191 base::WaitableEvent::InitialState::NOT_SIGNALED);
191 a->task_runner()->PostTask( 192 a->task_runner()->PostTask(FROM_HERE,
192 FROM_HERE, 193 base::BindOnce(&base::WaitableEvent::Wait,
193 base::Bind(&base::WaitableEvent::Wait, base::Unretained(&block_event))); 194 base::Unretained(&block_event)));
194 195
195 a->StopSoon(); 196 a->StopSoon();
196 EXPECT_TRUE(a->IsRunning()); 197 EXPECT_TRUE(a->IsRunning());
197 198
198 // Unblock the task and give a bit of extra time to unwind QuitWhenIdle(). 199 // Unblock the task and give a bit of extra time to unwind QuitWhenIdle().
199 block_event.Signal(); 200 block_event.Signal();
200 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20)); 201 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
201 202
202 // The thread should now have stopped on its own. 203 // The thread should now have stopped on its own.
203 EXPECT_FALSE(a->IsRunning()); 204 EXPECT_FALSE(a->IsRunning());
204 } 205 }
205 #endif 206 #endif
206 207
207 TEST_F(ThreadTest, TwoTasksOnJoinableThread) { 208 TEST_F(ThreadTest, TwoTasksOnJoinableThread) {
208 bool was_invoked = false; 209 bool was_invoked = false;
209 { 210 {
210 Thread a("TwoTasksOnJoinableThread"); 211 Thread a("TwoTasksOnJoinableThread");
211 EXPECT_TRUE(a.Start()); 212 EXPECT_TRUE(a.Start());
212 EXPECT_TRUE(a.message_loop()); 213 EXPECT_TRUE(a.message_loop());
213 214
214 // Test that all events are dispatched before the Thread object is 215 // Test that all events are dispatched before the Thread object is
215 // destroyed. We do this by dispatching a sleep event before the 216 // destroyed. We do this by dispatching a sleep event before the
216 // event that will toggle our sentinel value. 217 // event that will toggle our sentinel value.
217 a.task_runner()->PostTask( 218 a.task_runner()->PostTask(
218 FROM_HERE, base::Bind(static_cast<void (*)(base::TimeDelta)>( 219 FROM_HERE, base::BindOnce(static_cast<void (*)(base::TimeDelta)>(
219 &base::PlatformThread::Sleep), 220 &base::PlatformThread::Sleep),
220 base::TimeDelta::FromMilliseconds(20))); 221 base::TimeDelta::FromMilliseconds(20)));
221 a.task_runner()->PostTask(FROM_HERE, 222 a.task_runner()->PostTask(FROM_HERE,
222 base::Bind(&ToggleValue, &was_invoked)); 223 base::BindOnce(&ToggleValue, &was_invoked));
223 } 224 }
224 EXPECT_TRUE(was_invoked); 225 EXPECT_TRUE(was_invoked);
225 } 226 }
226 227
227 TEST_F(ThreadTest, DestroyWhileRunningIsSafe) { 228 TEST_F(ThreadTest, DestroyWhileRunningIsSafe) {
228 Thread a("DestroyWhileRunningIsSafe"); 229 Thread a("DestroyWhileRunningIsSafe");
229 EXPECT_TRUE(a.Start()); 230 EXPECT_TRUE(a.Start());
230 EXPECT_TRUE(a.WaitUntilThreadStarted()); 231 EXPECT_TRUE(a.WaitUntilThreadStarted());
231 } 232 }
232 233
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 // TODO(gab): Enable this test in conjunction with re-enabling the sequence 279 // TODO(gab): Enable this test in conjunction with re-enabling the sequence
279 // check in Thread::Stop() as part of http://crbug.com/629139. 280 // check in Thread::Stop() as part of http://crbug.com/629139.
280 TEST_F(ThreadTest, DISABLED_StopOnNonOwningThreadIsDeath) { 281 TEST_F(ThreadTest, DISABLED_StopOnNonOwningThreadIsDeath) {
281 Thread a("StopOnNonOwningThreadDeath"); 282 Thread a("StopOnNonOwningThreadDeath");
282 EXPECT_TRUE(a.StartAndWaitForTesting()); 283 EXPECT_TRUE(a.StartAndWaitForTesting());
283 284
284 Thread b("NonOwningThread"); 285 Thread b("NonOwningThread");
285 b.Start(); 286 b.Start();
286 EXPECT_DCHECK_DEATH({ 287 EXPECT_DCHECK_DEATH({
287 // Stopping |a| on |b| isn't allowed. 288 // Stopping |a| on |b| isn't allowed.
288 b.task_runner()->PostTask(FROM_HERE, 289 b.task_runner()->PostTask(
289 base::Bind(&Thread::Stop, base::Unretained(&a))); 290 FROM_HERE, base::BindOnce(&Thread::Stop, base::Unretained(&a)));
290 // Block here so the DCHECK on |b| always happens in this scope. 291 // Block here so the DCHECK on |b| always happens in this scope.
291 base::PlatformThread::Sleep(base::TimeDelta::Max()); 292 base::PlatformThread::Sleep(base::TimeDelta::Max());
292 }); 293 });
293 } 294 }
294 295
295 TEST_F(ThreadTest, TransferOwnershipAndStop) { 296 TEST_F(ThreadTest, TransferOwnershipAndStop) {
296 std::unique_ptr<Thread> a = 297 std::unique_ptr<Thread> a =
297 base::MakeUnique<Thread>("TransferOwnershipAndStop"); 298 base::MakeUnique<Thread>("TransferOwnershipAndStop");
298 EXPECT_TRUE(a->StartAndWaitForTesting()); 299 EXPECT_TRUE(a->StartAndWaitForTesting());
299 EXPECT_TRUE(a->IsRunning()); 300 EXPECT_TRUE(a->IsRunning());
300 301
301 Thread b("TakingOwnershipThread"); 302 Thread b("TakingOwnershipThread");
302 b.Start(); 303 b.Start();
303 304
304 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, 305 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
305 base::WaitableEvent::InitialState::NOT_SIGNALED); 306 base::WaitableEvent::InitialState::NOT_SIGNALED);
306 307
307 // a->DetachFromSequence() should allow |b| to use |a|'s Thread API. 308 // a->DetachFromSequence() should allow |b| to use |a|'s Thread API.
308 a->DetachFromSequence(); 309 a->DetachFromSequence();
309 b.task_runner()->PostTask( 310 b.task_runner()->PostTask(
310 FROM_HERE, base::Bind( 311 FROM_HERE, base::BindOnce(
311 [](std::unique_ptr<Thread> thread_to_stop, 312 [](std::unique_ptr<Thread> thread_to_stop,
312 base::WaitableEvent* event_to_signal) -> void { 313 base::WaitableEvent* event_to_signal) -> void {
313 thread_to_stop->Stop(); 314 thread_to_stop->Stop();
314 event_to_signal->Signal(); 315 event_to_signal->Signal();
315 }, 316 },
316 base::Passed(&a), base::Unretained(&event))); 317 base::Passed(&a), base::Unretained(&event)));
317 318
318 event.Wait(); 319 event.Wait();
319 } 320 }
320 321
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 Thread::Options options; 355 Thread::Options options;
355 options.joinable = false; 356 options.joinable = false;
356 EXPECT_TRUE(a->StartWithOptions(options)); 357 EXPECT_TRUE(a->StartWithOptions(options));
357 EXPECT_TRUE(a->message_loop()); 358 EXPECT_TRUE(a->message_loop());
358 EXPECT_TRUE(a->IsRunning()); 359 EXPECT_TRUE(a->IsRunning());
359 360
360 // Signaled when last task on |a| is processed. 361 // Signaled when last task on |a| is processed.
361 base::WaitableEvent last_task_event( 362 base::WaitableEvent last_task_event(
362 base::WaitableEvent::ResetPolicy::AUTOMATIC, 363 base::WaitableEvent::ResetPolicy::AUTOMATIC,
363 base::WaitableEvent::InitialState::NOT_SIGNALED); 364 base::WaitableEvent::InitialState::NOT_SIGNALED);
364 a->task_runner()->PostTask(FROM_HERE, 365 a->task_runner()->PostTask(
365 base::Bind(&base::WaitableEvent::Signal, 366 FROM_HERE, base::BindOnce(&base::WaitableEvent::Signal,
366 base::Unretained(&last_task_event))); 367 base::Unretained(&last_task_event)));
367 368
368 // StopSoon() is non-blocking, Yield() to |a|, wait for last task to be 369 // StopSoon() is non-blocking, Yield() to |a|, wait for last task to be
369 // processed and a little more for QuitWhenIdle() to unwind before considering 370 // processed and a little more for QuitWhenIdle() to unwind before considering
370 // the thread "stopped". 371 // the thread "stopped".
371 a->StopSoon(); 372 a->StopSoon();
372 base::PlatformThread::YieldCurrentThread(); 373 base::PlatformThread::YieldCurrentThread();
373 last_task_event.Wait(); 374 last_task_event.Wait();
374 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20)); 375 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
375 376
376 // This test assumes that the above was sufficient to let the thread fully 377 // This test assumes that the above was sufficient to let the thread fully
(...skipping 15 matching lines...) Expand all
392 Thread a("ThreadId0"); 393 Thread a("ThreadId0");
393 Thread b("ThreadId1"); 394 Thread b("ThreadId1");
394 a.Start(); 395 a.Start();
395 b.Start(); 396 b.Start();
396 397
397 // Post a task that calls GetThreadId() on the created thread. 398 // Post a task that calls GetThreadId() on the created thread.
398 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, 399 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
399 base::WaitableEvent::InitialState::NOT_SIGNALED); 400 base::WaitableEvent::InitialState::NOT_SIGNALED);
400 base::PlatformThreadId id_from_new_thread; 401 base::PlatformThreadId id_from_new_thread;
401 a.task_runner()->PostTask( 402 a.task_runner()->PostTask(
402 FROM_HERE, base::Bind(ReturnThreadId, &a, &id_from_new_thread, &event)); 403 FROM_HERE,
404 base::BindOnce(ReturnThreadId, &a, &id_from_new_thread, &event));
403 405
404 // Call GetThreadId() on the current thread before calling event.Wait() so 406 // Call GetThreadId() on the current thread before calling event.Wait() so
405 // that this test can find a race issue with TSAN. 407 // that this test can find a race issue with TSAN.
406 base::PlatformThreadId id_from_current_thread = a.GetThreadId(); 408 base::PlatformThreadId id_from_current_thread = a.GetThreadId();
407 409
408 // Check if GetThreadId() returns consistent value in both threads. 410 // Check if GetThreadId() returns consistent value in both threads.
409 event.Wait(); 411 event.Wait();
410 EXPECT_EQ(id_from_current_thread, id_from_new_thread); 412 EXPECT_EQ(id_from_current_thread, id_from_new_thread);
411 413
412 // A started thread should have a valid ID. 414 // A started thread should have a valid ID.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 { 453 {
452 // Start a thread which writes its event into |captured_events|. 454 // Start a thread which writes its event into |captured_events|.
453 CaptureToEventList t(&captured_events); 455 CaptureToEventList t(&captured_events);
454 EXPECT_TRUE(t.Start()); 456 EXPECT_TRUE(t.Start());
455 EXPECT_TRUE(t.message_loop()); 457 EXPECT_TRUE(t.message_loop());
456 EXPECT_TRUE(t.IsRunning()); 458 EXPECT_TRUE(t.IsRunning());
457 459
458 // Register an observer that writes into |captured_events| once the 460 // Register an observer that writes into |captured_events| once the
459 // thread's message loop is destroyed. 461 // thread's message loop is destroyed.
460 t.task_runner()->PostTask( 462 t.task_runner()->PostTask(
461 FROM_HERE, base::Bind(&RegisterDestructionObserver, 463 FROM_HERE,
462 base::Unretained(&loop_destruction_observer))); 464 base::BindOnce(&RegisterDestructionObserver,
465 base::Unretained(&loop_destruction_observer)));
463 466
464 // Upon leaving this scope, the thread is deleted. 467 // Upon leaving this scope, the thread is deleted.
465 } 468 }
466 469
467 // Check the order of events during shutdown. 470 // Check the order of events during shutdown.
468 ASSERT_EQ(static_cast<size_t>(THREAD_NUM_EVENTS), captured_events.size()); 471 ASSERT_EQ(static_cast<size_t>(THREAD_NUM_EVENTS), captured_events.size());
469 EXPECT_EQ(THREAD_EVENT_INIT, captured_events[0]); 472 EXPECT_EQ(THREAD_EVENT_INIT, captured_events[0]);
470 EXPECT_EQ(THREAD_EVENT_CLEANUP, captured_events[1]); 473 EXPECT_EQ(THREAD_EVENT_CLEANUP, captured_events[1]);
471 EXPECT_EQ(THREAD_EVENT_MESSAGE_LOOP_DESTROYED, captured_events[2]); 474 EXPECT_EQ(THREAD_EVENT_MESSAGE_LOOP_DESTROYED, captured_events[2]);
472 } 475 }
(...skipping 23 matching lines...) Expand all
496 a.FlushForTesting(); 499 a.FlushForTesting();
497 500
498 constexpr base::TimeDelta kSleepPerTestTask = 501 constexpr base::TimeDelta kSleepPerTestTask =
499 base::TimeDelta::FromMilliseconds(50); 502 base::TimeDelta::FromMilliseconds(50);
500 constexpr size_t kNumSleepTasks = 5; 503 constexpr size_t kNumSleepTasks = 5;
501 504
502 const base::TimeTicks ticks_before_post = base::TimeTicks::Now(); 505 const base::TimeTicks ticks_before_post = base::TimeTicks::Now();
503 506
504 for (size_t i = 0; i < kNumSleepTasks; ++i) { 507 for (size_t i = 0; i < kNumSleepTasks; ++i) {
505 a.task_runner()->PostTask( 508 a.task_runner()->PostTask(
506 FROM_HERE, base::Bind(&base::PlatformThread::Sleep, kSleepPerTestTask)); 509 FROM_HERE,
510 base::BindOnce(&base::PlatformThread::Sleep, kSleepPerTestTask));
507 } 511 }
508 512
509 // All tasks should have executed, as reflected by the elapsed time. 513 // All tasks should have executed, as reflected by the elapsed time.
510 a.FlushForTesting(); 514 a.FlushForTesting();
511 EXPECT_GE(base::TimeTicks::Now() - ticks_before_post, 515 EXPECT_GE(base::TimeTicks::Now() - ticks_before_post,
512 kNumSleepTasks * kSleepPerTestTask); 516 kNumSleepTasks * kSleepPerTestTask);
513 517
514 a.Stop(); 518 a.Stop();
515 519
516 // Flushing a stopped thread should be a no-op. 520 // Flushing a stopped thread should be a no-op.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 EXPECT_FALSE(a.IsRunning()); 554 EXPECT_FALSE(a.IsRunning());
551 a.VerifyUsingExternalMessageLoop(false); 555 a.VerifyUsingExternalMessageLoop(false);
552 556
553 a.InstallMessageLoop(); 557 a.InstallMessageLoop();
554 EXPECT_TRUE(a.message_loop()); 558 EXPECT_TRUE(a.message_loop());
555 EXPECT_TRUE(a.IsRunning()); 559 EXPECT_TRUE(a.IsRunning());
556 a.VerifyUsingExternalMessageLoop(true); 560 a.VerifyUsingExternalMessageLoop(true);
557 561
558 bool ran = false; 562 bool ran = false;
559 a.task_runner()->PostTask( 563 a.task_runner()->PostTask(
560 FROM_HERE, base::Bind([](bool* toggled) { *toggled = true; }, &ran)); 564 FROM_HERE, base::BindOnce([](bool* toggled) { *toggled = true; }, &ran));
561 base::RunLoop().RunUntilIdle(); 565 base::RunLoop().RunUntilIdle();
562 EXPECT_TRUE(ran); 566 EXPECT_TRUE(ran);
563 567
564 a.Stop(); 568 a.Stop();
565 EXPECT_FALSE(a.message_loop()); 569 EXPECT_FALSE(a.message_loop());
566 EXPECT_FALSE(a.IsRunning()); 570 EXPECT_FALSE(a.IsRunning());
567 a.VerifyUsingExternalMessageLoop(true); 571 a.VerifyUsingExternalMessageLoop(true);
568 572
569 // Confirm that running any remaining tasks posted from Stop() goes smoothly 573 // Confirm that running any remaining tasks posted from Stop() goes smoothly
570 // (e.g. https://codereview.chromium.org/2135413003/#ps300001 crashed if 574 // (e.g. https://codereview.chromium.org/2135413003/#ps300001 crashed if
571 // StopSoon() posted Thread::ThreadQuitHelper() while |run_loop_| was null). 575 // StopSoon() posted Thread::ThreadQuitHelper() while |run_loop_| was null).
572 base::RunLoop().RunUntilIdle(); 576 base::RunLoop().RunUntilIdle();
573 } 577 }
OLDNEW
« no previous file with comments | « base/threading/thread_perftest.cc ('k') | base/threading/worker_pool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698