Home | History | Annotate | Download | only in threading
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/threading/thread.h"
      6 
      7 #include <stddef.h>
      8 #include <stdint.h>
      9 
     10 #include <vector>
     11 
     12 #include "base/bind.h"
     13 #include "base/debug/leak_annotations.h"
     14 #include "base/macros.h"
     15 #include "base/memory/ptr_util.h"
     16 #include "base/message_loop/message_loop.h"
     17 #include "base/run_loop.h"
     18 #include "base/single_thread_task_runner.h"
     19 #include "base/synchronization/waitable_event.h"
     20 #include "base/test/gtest_util.h"
     21 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
     22 #include "base/threading/platform_thread.h"
     23 #include "base/time/time.h"
     24 #include "build/build_config.h"
     25 #include "testing/gtest/include/gtest/gtest.h"
     26 #include "testing/platform_test.h"
     27 
     28 using base::Thread;
     29 
     30 typedef PlatformTest ThreadTest;
     31 
     32 namespace {
     33 
     34 void ToggleValue(bool* value) {
     35   ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean "
     36                        "in base/thread_unittest");
     37   *value = !*value;
     38 }
     39 
     40 class SleepInsideInitThread : public Thread {
     41  public:
     42   SleepInsideInitThread() : Thread("none") {
     43     init_called_ = false;
     44     ANNOTATE_BENIGN_RACE(
     45         this, "Benign test-only data race on vptr - http://crbug.com/98219");
     46   }
     47   ~SleepInsideInitThread() override { Stop(); }
     48 
     49   void Init() override {
     50     base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(500));
     51     init_called_ = true;
     52   }
     53   bool InitCalled() { return init_called_; }
     54 
     55  private:
     56   bool init_called_;
     57 
     58   DISALLOW_COPY_AND_ASSIGN(SleepInsideInitThread);
     59 };
     60 
     61 enum ThreadEvent {
     62   // Thread::Init() was called.
     63   THREAD_EVENT_INIT = 0,
     64 
     65   // The MessageLoop for the thread was deleted.
     66   THREAD_EVENT_MESSAGE_LOOP_DESTROYED,
     67 
     68   // Thread::CleanUp() was called.
     69   THREAD_EVENT_CLEANUP,
     70 
     71   // Keep at end of list.
     72   THREAD_NUM_EVENTS
     73 };
     74 
     75 typedef std::vector<ThreadEvent> EventList;
     76 
     77 class CaptureToEventList : public Thread {
     78  public:
     79   // This Thread pushes events into the vector |event_list| to show
     80   // the order they occured in. |event_list| must remain valid for the
     81   // lifetime of this thread.
     82   explicit CaptureToEventList(EventList* event_list)
     83       : Thread("none"),
     84         event_list_(event_list) {
     85   }
     86 
     87   ~CaptureToEventList() override { Stop(); }
     88 
     89   void Init() override { event_list_->push_back(THREAD_EVENT_INIT); }
     90 
     91   void CleanUp() override { event_list_->push_back(THREAD_EVENT_CLEANUP); }
     92 
     93  private:
     94   EventList* event_list_;
     95 
     96   DISALLOW_COPY_AND_ASSIGN(CaptureToEventList);
     97 };
     98 
     99 // Observer that writes a value into |event_list| when a message loop has been
    100 // destroyed.
    101 class CapturingDestructionObserver
    102     : public base::MessageLoop::DestructionObserver {
    103  public:
    104   // |event_list| must remain valid throughout the observer's lifetime.
    105   explicit CapturingDestructionObserver(EventList* event_list)
    106       : event_list_(event_list) {
    107   }
    108 
    109   // DestructionObserver implementation:
    110   void WillDestroyCurrentMessageLoop() override {
    111     event_list_->push_back(THREAD_EVENT_MESSAGE_LOOP_DESTROYED);
    112     event_list_ = NULL;
    113   }
    114 
    115  private:
    116   EventList* event_list_;
    117 
    118   DISALLOW_COPY_AND_ASSIGN(CapturingDestructionObserver);
    119 };
    120 
    121 // Task that adds a destruction observer to the current message loop.
    122 void RegisterDestructionObserver(
    123     base::MessageLoop::DestructionObserver* observer) {
    124   base::MessageLoop::current()->AddDestructionObserver(observer);
    125 }
    126 
    127 // Task that calls GetThreadId() of |thread|, stores the result into |id|, then
    128 // signal |event|.
    129 void ReturnThreadId(base::Thread* thread,
    130                     base::PlatformThreadId* id,
    131                     base::WaitableEvent* event) {
    132   *id = thread->GetThreadId();
    133   event->Signal();
    134 }
    135 
    136 }  // namespace
    137 
    138 TEST_F(ThreadTest, StartWithOptions_StackSize) {
    139   Thread a("StartWithStackSize");
    140   // Ensure that the thread can work with only 12 kb and still process a
    141   // message. At the same time, we should scale with the bitness of the system
    142   // where 12 kb is definitely not enough.
    143   // 12 kb = 3072 Slots on a 32-bit system, so we'll scale based off of that.
    144   Thread::Options options;
    145 #if defined(ADDRESS_SANITIZER) || !defined(NDEBUG)
    146   // ASan bloats the stack variables and overflows the 3072 slot stack. Some
    147   // debug builds also grow the stack too much.
    148   options.stack_size = 2 * 3072 * sizeof(uintptr_t);
    149 #else
    150   options.stack_size = 3072 * sizeof(uintptr_t);
    151 #endif
    152   EXPECT_TRUE(a.StartWithOptions(options));
    153   EXPECT_TRUE(a.message_loop());
    154   EXPECT_TRUE(a.IsRunning());
    155 
    156   base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
    157                             base::WaitableEvent::InitialState::NOT_SIGNALED);
    158   a.task_runner()->PostTask(FROM_HERE, base::Bind(&base::WaitableEvent::Signal,
    159                                                   base::Unretained(&event)));
    160   event.Wait();
    161 }
    162 
    163 // Intentional test-only race for otherwise untestable code, won't fix.
    164 // https://crbug.com/634383
    165 #if !defined(THREAD_SANITIZER)
    166 TEST_F(ThreadTest, StartWithOptions_NonJoinable) {
    167   Thread* a = new Thread("StartNonJoinable");
    168   // Non-joinable threads have to be leaked for now (see
    169   // Thread::Options::joinable for details).
    170   ANNOTATE_LEAKING_OBJECT_PTR(a);
    171 
    172   Thread::Options options;
    173   options.joinable = false;
    174   EXPECT_TRUE(a->StartWithOptions(options));
    175   EXPECT_TRUE(a->message_loop());
    176   EXPECT_TRUE(a->IsRunning());
    177 
    178   // Without this call this test is racy. The above IsRunning() succeeds because
    179   // of an early-return condition while between Start() and StopSoon(), after
    180   // invoking StopSoon() below this early-return condition is no longer
    181   // 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   // 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   EXPECT_TRUE(a->WaitUntilThreadStarted());
    186 
    187   // Make the thread block until |block_event| is signaled.
    188   base::WaitableEvent block_event(
    189       base::WaitableEvent::ResetPolicy::AUTOMATIC,
    190       base::WaitableEvent::InitialState::NOT_SIGNALED);
    191   a->task_runner()->PostTask(
    192       FROM_HERE,
    193       base::Bind(&base::WaitableEvent::Wait, base::Unretained(&block_event)));
    194 
    195   a->StopSoon();
    196   EXPECT_TRUE(a->IsRunning());
    197 
    198   // Unblock the task and give a bit of extra time to unwind QuitWhenIdle().
    199   block_event.Signal();
    200   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
    201 
    202   // The thread should now have stopped on its own.
    203   EXPECT_FALSE(a->IsRunning());
    204 }
    205 #endif
    206 
    207 TEST_F(ThreadTest, TwoTasksOnJoinableThread) {
    208   bool was_invoked = false;
    209   {
    210     Thread a("TwoTasksOnJoinableThread");
    211     EXPECT_TRUE(a.Start());
    212     EXPECT_TRUE(a.message_loop());
    213 
    214     // Test that all events are dispatched before the Thread object is
    215     // destroyed.  We do this by dispatching a sleep event before the
    216     // event that will toggle our sentinel value.
    217     a.task_runner()->PostTask(
    218         FROM_HERE, base::Bind(static_cast<void (*)(base::TimeDelta)>(
    219                                   &base::PlatformThread::Sleep),
    220                               base::TimeDelta::FromMilliseconds(20)));
    221     a.task_runner()->PostTask(FROM_HERE,
    222                               base::Bind(&ToggleValue, &was_invoked));
    223   }
    224   EXPECT_TRUE(was_invoked);
    225 }
    226 
    227 TEST_F(ThreadTest, DestroyWhileRunningIsSafe) {
    228   Thread a("DestroyWhileRunningIsSafe");
    229   EXPECT_TRUE(a.Start());
    230   EXPECT_TRUE(a.WaitUntilThreadStarted());
    231 }
    232 
    233 // TODO(gab): Enable this test when destroying a non-joinable Thread instance
    234 // is supported (proposal @ https://crbug.com/629139#c14).
    235 TEST_F(ThreadTest, DISABLED_DestroyWhileRunningNonJoinableIsSafe) {
    236   {
    237     Thread a("DestroyWhileRunningNonJoinableIsSafe");
    238     Thread::Options options;
    239     options.joinable = false;
    240     EXPECT_TRUE(a.StartWithOptions(options));
    241     EXPECT_TRUE(a.WaitUntilThreadStarted());
    242   }
    243 
    244   // Attempt to catch use-after-frees from the non-joinable thread in the
    245   // scope of this test if any.
    246   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
    247 }
    248 
    249 TEST_F(ThreadTest, StopSoon) {
    250   Thread a("StopSoon");
    251   EXPECT_TRUE(a.Start());
    252   EXPECT_TRUE(a.message_loop());
    253   EXPECT_TRUE(a.IsRunning());
    254   a.StopSoon();
    255   a.Stop();
    256   EXPECT_FALSE(a.message_loop());
    257   EXPECT_FALSE(a.IsRunning());
    258 }
    259 
    260 TEST_F(ThreadTest, StopTwiceNop) {
    261   Thread a("StopTwiceNop");
    262   EXPECT_TRUE(a.Start());
    263   EXPECT_TRUE(a.message_loop());
    264   EXPECT_TRUE(a.IsRunning());
    265   a.StopSoon();
    266   // Calling StopSoon() a second time should be a nop.
    267   a.StopSoon();
    268   a.Stop();
    269   // Same with Stop().
    270   a.Stop();
    271   EXPECT_FALSE(a.message_loop());
    272   EXPECT_FALSE(a.IsRunning());
    273   // Calling them when not running should also nop.
    274   a.StopSoon();
    275   a.Stop();
    276 }
    277 
    278 // 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 TEST_F(ThreadTest, DISABLED_StopOnNonOwningThreadIsDeath) {
    281   Thread a("StopOnNonOwningThreadDeath");
    282   EXPECT_TRUE(a.StartAndWaitForTesting());
    283 
    284   Thread b("NonOwningThread");
    285   b.Start();
    286   EXPECT_DCHECK_DEATH({
    287     // Stopping |a| on |b| isn't allowed.
    288     b.task_runner()->PostTask(FROM_HERE,
    289                               base::Bind(&Thread::Stop, base::Unretained(&a)));
    290     // Block here so the DCHECK on |b| always happens in this scope.
    291     base::PlatformThread::Sleep(base::TimeDelta::Max());
    292   });
    293 }
    294 
    295 TEST_F(ThreadTest, TransferOwnershipAndStop) {
    296   std::unique_ptr<Thread> a =
    297       base::MakeUnique<Thread>("TransferOwnershipAndStop");
    298   EXPECT_TRUE(a->StartAndWaitForTesting());
    299   EXPECT_TRUE(a->IsRunning());
    300 
    301   Thread b("TakingOwnershipThread");
    302   b.Start();
    303 
    304   base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
    305                             base::WaitableEvent::InitialState::NOT_SIGNALED);
    306 
    307   // a->DetachFromSequence() should allow |b| to use |a|'s Thread API.
    308   a->DetachFromSequence();
    309   b.task_runner()->PostTask(
    310       FROM_HERE, base::Bind(
    311                      [](std::unique_ptr<Thread> thread_to_stop,
    312                         base::WaitableEvent* event_to_signal) -> void {
    313                        thread_to_stop->Stop();
    314                        event_to_signal->Signal();
    315                      },
    316                      base::Passed(&a), base::Unretained(&event)));
    317 
    318   event.Wait();
    319 }
    320 
    321 TEST_F(ThreadTest, StartTwice) {
    322   Thread a("StartTwice");
    323 
    324   EXPECT_FALSE(a.message_loop());
    325   EXPECT_FALSE(a.IsRunning());
    326 
    327   EXPECT_TRUE(a.Start());
    328   EXPECT_TRUE(a.message_loop());
    329   EXPECT_TRUE(a.IsRunning());
    330 
    331   a.Stop();
    332   EXPECT_FALSE(a.message_loop());
    333   EXPECT_FALSE(a.IsRunning());
    334 
    335   EXPECT_TRUE(a.Start());
    336   EXPECT_TRUE(a.message_loop());
    337   EXPECT_TRUE(a.IsRunning());
    338 
    339   a.Stop();
    340   EXPECT_FALSE(a.message_loop());
    341   EXPECT_FALSE(a.IsRunning());
    342 }
    343 
    344 // Intentional test-only race for otherwise untestable code, won't fix.
    345 // https://crbug.com/634383
    346 #if !defined(THREAD_SANITIZER)
    347 TEST_F(ThreadTest, StartTwiceNonJoinableNotAllowed) {
    348   LOG(ERROR) << __FUNCTION__;
    349   Thread* a = new Thread("StartTwiceNonJoinable");
    350   // Non-joinable threads have to be leaked for now (see
    351   // Thread::Options::joinable for details).
    352   ANNOTATE_LEAKING_OBJECT_PTR(a);
    353 
    354   Thread::Options options;
    355   options.joinable = false;
    356   EXPECT_TRUE(a->StartWithOptions(options));
    357   EXPECT_TRUE(a->message_loop());
    358   EXPECT_TRUE(a->IsRunning());
    359 
    360   // Signaled when last task on |a| is processed.
    361   base::WaitableEvent last_task_event(
    362       base::WaitableEvent::ResetPolicy::AUTOMATIC,
    363       base::WaitableEvent::InitialState::NOT_SIGNALED);
    364   a->task_runner()->PostTask(FROM_HERE,
    365                             base::Bind(&base::WaitableEvent::Signal,
    366                                        base::Unretained(&last_task_event)));
    367 
    368   // 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   // the thread "stopped".
    371   a->StopSoon();
    372   base::PlatformThread::YieldCurrentThread();
    373   last_task_event.Wait();
    374   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
    375 
    376   // This test assumes that the above was sufficient to let the thread fully
    377   // stop.
    378   ASSERT_FALSE(a->IsRunning());
    379 
    380   // Restarting it should not be allowed.
    381   EXPECT_DCHECK_DEATH(a->Start());
    382 }
    383 #endif
    384 
    385 TEST_F(ThreadTest, ThreadName) {
    386   Thread a("ThreadName");
    387   EXPECT_TRUE(a.Start());
    388   EXPECT_EQ("ThreadName", a.thread_name());
    389 }
    390 
    391 TEST_F(ThreadTest, ThreadId) {
    392   Thread a("ThreadId0");
    393   Thread b("ThreadId1");
    394   a.Start();
    395   b.Start();
    396 
    397   // Post a task that calls GetThreadId() on the created thread.
    398   base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
    399                             base::WaitableEvent::InitialState::NOT_SIGNALED);
    400   base::PlatformThreadId id_from_new_thread;
    401   a.task_runner()->PostTask(
    402       FROM_HERE, base::Bind(ReturnThreadId, &a, &id_from_new_thread, &event));
    403 
    404   // Call GetThreadId() on the current thread before calling event.Wait() so
    405   // that this test can find a race issue with TSAN.
    406   base::PlatformThreadId id_from_current_thread = a.GetThreadId();
    407 
    408   // Check if GetThreadId() returns consistent value in both threads.
    409   event.Wait();
    410   EXPECT_EQ(id_from_current_thread, id_from_new_thread);
    411 
    412   // A started thread should have a valid ID.
    413   EXPECT_NE(base::kInvalidThreadId, a.GetThreadId());
    414   EXPECT_NE(base::kInvalidThreadId, b.GetThreadId());
    415 
    416   // Each thread should have a different thread ID.
    417   EXPECT_NE(a.GetThreadId(), b.GetThreadId());
    418 }
    419 
    420 TEST_F(ThreadTest, ThreadIdWithRestart) {
    421   Thread a("ThreadIdWithRestart");
    422   base::PlatformThreadId previous_id = base::kInvalidThreadId;
    423 
    424   for (size_t i = 0; i < 16; ++i) {
    425     EXPECT_TRUE(a.Start());
    426     base::PlatformThreadId current_id = a.GetThreadId();
    427     EXPECT_NE(previous_id, current_id);
    428     previous_id = current_id;
    429     a.Stop();
    430   }
    431 }
    432 
    433 // Make sure Init() is called after Start() and before
    434 // WaitUntilThreadInitialized() returns.
    435 TEST_F(ThreadTest, SleepInsideInit) {
    436   SleepInsideInitThread t;
    437   EXPECT_FALSE(t.InitCalled());
    438   t.StartAndWaitForTesting();
    439   EXPECT_TRUE(t.InitCalled());
    440 }
    441 
    442 // Make sure that the destruction sequence is:
    443 //
    444 //  (1) Thread::CleanUp()
    445 //  (2) MessageLoop::~MessageLoop()
    446 //      MessageLoop::DestructionObservers called.
    447 TEST_F(ThreadTest, CleanUp) {
    448   EventList captured_events;
    449   CapturingDestructionObserver loop_destruction_observer(&captured_events);
    450 
    451   {
    452     // Start a thread which writes its event into |captured_events|.
    453     CaptureToEventList t(&captured_events);
    454     EXPECT_TRUE(t.Start());
    455     EXPECT_TRUE(t.message_loop());
    456     EXPECT_TRUE(t.IsRunning());
    457 
    458     // Register an observer that writes into |captured_events| once the
    459     // thread's message loop is destroyed.
    460     t.task_runner()->PostTask(
    461         FROM_HERE, base::Bind(&RegisterDestructionObserver,
    462                               base::Unretained(&loop_destruction_observer)));
    463 
    464     // Upon leaving this scope, the thread is deleted.
    465   }
    466 
    467   // Check the order of events during shutdown.
    468   ASSERT_EQ(static_cast<size_t>(THREAD_NUM_EVENTS), captured_events.size());
    469   EXPECT_EQ(THREAD_EVENT_INIT, captured_events[0]);
    470   EXPECT_EQ(THREAD_EVENT_CLEANUP, captured_events[1]);
    471   EXPECT_EQ(THREAD_EVENT_MESSAGE_LOOP_DESTROYED, captured_events[2]);
    472 }
    473 
    474 TEST_F(ThreadTest, ThreadNotStarted) {
    475   Thread a("Inert");
    476   EXPECT_FALSE(a.task_runner());
    477 }
    478 
    479 TEST_F(ThreadTest, MultipleWaitUntilThreadStarted) {
    480   Thread a("MultipleWaitUntilThreadStarted");
    481   EXPECT_TRUE(a.Start());
    482   // It's OK to call WaitUntilThreadStarted() multiple times.
    483   EXPECT_TRUE(a.WaitUntilThreadStarted());
    484   EXPECT_TRUE(a.WaitUntilThreadStarted());
    485 }
    486 
    487 TEST_F(ThreadTest, FlushForTesting) {
    488   Thread a("FlushForTesting");
    489 
    490   // Flushing a non-running thread should be a no-op.
    491   a.FlushForTesting();
    492 
    493   ASSERT_TRUE(a.Start());
    494 
    495   // Flushing a thread with no tasks shouldn't block.
    496   a.FlushForTesting();
    497 
    498   constexpr base::TimeDelta kSleepPerTestTask =
    499       base::TimeDelta::FromMilliseconds(50);
    500   constexpr size_t kNumSleepTasks = 5;
    501 
    502   const base::TimeTicks ticks_before_post = base::TimeTicks::Now();
    503 
    504   for (size_t i = 0; i < kNumSleepTasks; ++i) {
    505     a.task_runner()->PostTask(
    506         FROM_HERE, base::Bind(&base::PlatformThread::Sleep, kSleepPerTestTask));
    507   }
    508 
    509   // All tasks should have executed, as reflected by the elapsed time.
    510   a.FlushForTesting();
    511   EXPECT_GE(base::TimeTicks::Now() - ticks_before_post,
    512             kNumSleepTasks * kSleepPerTestTask);
    513 
    514   a.Stop();
    515 
    516   // Flushing a stopped thread should be a no-op.
    517   a.FlushForTesting();
    518 }
    519 
    520 namespace {
    521 
    522 // A Thread which uses a MessageLoop on the stack. It won't start a real
    523 // underlying thread (instead its messages can be processed by a RunLoop on the
    524 // stack).
    525 class ExternalMessageLoopThread : public Thread {
    526  public:
    527   ExternalMessageLoopThread() : Thread("ExternalMessageLoopThread") {}
    528 
    529   ~ExternalMessageLoopThread() override { Stop(); }
    530 
    531   void InstallMessageLoop() { SetMessageLoop(&external_message_loop_); }
    532 
    533   void VerifyUsingExternalMessageLoop(
    534       bool expected_using_external_message_loop) {
    535     EXPECT_EQ(expected_using_external_message_loop,
    536               using_external_message_loop());
    537   }
    538 
    539  private:
    540   base::MessageLoop external_message_loop_;
    541 
    542   DISALLOW_COPY_AND_ASSIGN(ExternalMessageLoopThread);
    543 };
    544 
    545 }  // namespace
    546 
    547 TEST_F(ThreadTest, ExternalMessageLoop) {
    548   ExternalMessageLoopThread a;
    549   EXPECT_FALSE(a.message_loop());
    550   EXPECT_FALSE(a.IsRunning());
    551   a.VerifyUsingExternalMessageLoop(false);
    552 
    553   a.InstallMessageLoop();
    554   EXPECT_TRUE(a.message_loop());
    555   EXPECT_TRUE(a.IsRunning());
    556   a.VerifyUsingExternalMessageLoop(true);
    557 
    558   bool ran = false;
    559   a.task_runner()->PostTask(
    560       FROM_HERE, base::Bind([](bool* toggled) { *toggled = true; }, &ran));
    561   base::RunLoop().RunUntilIdle();
    562   EXPECT_TRUE(ran);
    563 
    564   a.Stop();
    565   EXPECT_FALSE(a.message_loop());
    566   EXPECT_FALSE(a.IsRunning());
    567   a.VerifyUsingExternalMessageLoop(true);
    568 
    569   // Confirm that running any remaining tasks posted from Stop() goes smoothly
    570   // (e.g. https://codereview.chromium.org/2135413003/#ps300001 crashed if
    571   // StopSoon() posted Thread::ThreadQuitHelper() while |run_loop_| was null).
    572   base::RunLoop().RunUntilIdle();
    573 }
    574