// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/threading/thread.h"

#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/debug/leak_annotations.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_current.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/gtest_util.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

using base::Thread;

typedef PlatformTest ThreadTest;

namespace {

void ToggleValue(bool* value) {
  ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean "
                       "in base/thread_unittest");
  *value = !*value;
}

class SleepInsideInitThread : public Thread {
 public:
  SleepInsideInitThread() : Thread("none") {
    init_called_ = false;
    ANNOTATE_BENIGN_RACE(
        this, "Benign test-only data race on vptr - http://crbug.com/98219");
  }
  ~SleepInsideInitThread() override { Stop(); }

  void Init() override {
    base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(500));
    init_called_ = true;
  }
  bool InitCalled() { return init_called_; }

 private:
  bool init_called_;

  DISALLOW_COPY_AND_ASSIGN(SleepInsideInitThread);
};

enum ThreadEvent {
  // Thread::Init() was called.
  THREAD_EVENT_INIT = 0,

  // The MessageLoop for the thread was deleted.
  THREAD_EVENT_MESSAGE_LOOP_DESTROYED,

  // Thread::CleanUp() was called.
  THREAD_EVENT_CLEANUP,

  // Keep at end of list.
  THREAD_NUM_EVENTS
};

typedef std::vector<ThreadEvent> EventList;

class CaptureToEventList : public Thread {
 public:
  // This Thread pushes events into the vector |event_list| to show
  // the order they occured in. |event_list| must remain valid for the
  // lifetime of this thread.
  explicit CaptureToEventList(EventList* event_list)
      : Thread("none"),
        event_list_(event_list) {
  }

  ~CaptureToEventList() override { Stop(); }

  void Init() override { event_list_->push_back(THREAD_EVENT_INIT); }

  void CleanUp() override { event_list_->push_back(THREAD_EVENT_CLEANUP); }

 private:
  EventList* event_list_;

  DISALLOW_COPY_AND_ASSIGN(CaptureToEventList);
};

// Observer that writes a value into |event_list| when a message loop has been
// destroyed.
class CapturingDestructionObserver
    : public base::MessageLoopCurrent::DestructionObserver {
 public:
  // |event_list| must remain valid throughout the observer's lifetime.
  explicit CapturingDestructionObserver(EventList* event_list)
      : event_list_(event_list) {
  }

  // DestructionObserver implementation:
  void WillDestroyCurrentMessageLoop() override {
    event_list_->push_back(THREAD_EVENT_MESSAGE_LOOP_DESTROYED);
    event_list_ = nullptr;
  }

 private:
  EventList* event_list_;

  DISALLOW_COPY_AND_ASSIGN(CapturingDestructionObserver);
};

// Task that adds a destruction observer to the current message loop.
void RegisterDestructionObserver(
    base::MessageLoopCurrent::DestructionObserver* observer) {
  base::MessageLoopCurrent::Get()->AddDestructionObserver(observer);
}

// Task that calls GetThreadId() of |thread|, stores the result into |id|, then
// signal |event|.
void ReturnThreadId(base::Thread* thread,
                    base::PlatformThreadId* id,
                    base::WaitableEvent* event) {
  *id = thread->GetThreadId();
  event->Signal();
}

}  // namespace

TEST_F(ThreadTest, StartWithOptions_StackSize) {
  Thread a("StartWithStackSize");
  // Ensure that the thread can work with only 12 kb and still process a
  // message. At the same time, we should scale with the bitness of the system
  // where 12 kb is definitely not enough.
  // 12 kb = 3072 Slots on a 32-bit system, so we'll scale based off of that.
  Thread::Options options;
#if defined(ADDRESS_SANITIZER) || !defined(NDEBUG)
  // ASan bloats the stack variables and overflows the 3072 slot stack. Some
  // debug builds also grow the stack too much.
  options.stack_size = 2 * 3072 * sizeof(uintptr_t);
#else
  options.stack_size = 3072 * sizeof(uintptr_t);
#endif
  EXPECT_TRUE(a.StartWithOptions(options));
  EXPECT_TRUE(a.message_loop());
  EXPECT_TRUE(a.IsRunning());

  base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                            base::WaitableEvent::InitialState::NOT_SIGNALED);
  a.task_runner()->PostTask(
      FROM_HERE,
      base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event)));
  event.Wait();
}

// Intentional test-only race for otherwise untestable code, won't fix.
// https://crbug.com/634383
#if !defined(THREAD_SANITIZER)
TEST_F(ThreadTest, StartWithOptions_NonJoinable) {
  Thread* a = new Thread("StartNonJoinable");
  // Non-joinable threads have to be leaked for now (see
  // Thread::Options::joinable for details).
  ANNOTATE_LEAKING_OBJECT_PTR(a);

  Thread::Options options;
  options.joinable = false;
  EXPECT_TRUE(a->StartWithOptions(options));
  EXPECT_TRUE(a->message_loop());
  EXPECT_TRUE(a->IsRunning());

  // Without this call this test is racy. The above IsRunning() succeeds because
  // of an early-return condition while between Start() and StopSoon(), after
  // invoking StopSoon() below this early-return condition is no longer
  // satisfied and the real |is_running_| bit has to be checked. It could still
  // be false if the message loop hasn't started for real in practice. This is
  // only a requirement for this test because the non-joinable property forces
  // it to use StopSoon() and not wait for a complete Stop().
  EXPECT_TRUE(a->WaitUntilThreadStarted());

  // Make the thread block until |block_event| is signaled.
  base::WaitableEvent block_event(
      base::WaitableEvent::ResetPolicy::AUTOMATIC,
      base::WaitableEvent::InitialState::NOT_SIGNALED);
  a->task_runner()->PostTask(FROM_HERE,
                             base::BindOnce(&base::WaitableEvent::Wait,
                                            base::Unretained(&block_event)));

  a->StopSoon();
  EXPECT_TRUE(a->IsRunning());

  // Unblock the task and give a bit of extra time to unwind QuitWhenIdle().
  block_event.Signal();
  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));

  // The thread should now have stopped on its own.
  EXPECT_FALSE(a->IsRunning());
}
#endif

TEST_F(ThreadTest, TwoTasksOnJoinableThread) {
  bool was_invoked = false;
  {
    Thread a("TwoTasksOnJoinableThread");
    EXPECT_TRUE(a.Start());
    EXPECT_TRUE(a.message_loop());

    // Test that all events are dispatched before the Thread object is
    // destroyed.  We do this by dispatching a sleep event before the
    // event that will toggle our sentinel value.
    a.task_runner()->PostTask(
        FROM_HERE, base::BindOnce(static_cast<void (*)(base::TimeDelta)>(
                                      &base::PlatformThread::Sleep),
                                  base::TimeDelta::FromMilliseconds(20)));
    a.task_runner()->PostTask(FROM_HERE,
                              base::BindOnce(&ToggleValue, &was_invoked));
  }
  EXPECT_TRUE(was_invoked);
}

TEST_F(ThreadTest, DestroyWhileRunningIsSafe) {
  Thread a("DestroyWhileRunningIsSafe");
  EXPECT_TRUE(a.Start());
  EXPECT_TRUE(a.WaitUntilThreadStarted());
}

// TODO(gab): Enable this test when destroying a non-joinable Thread instance
// is supported (proposal @ https://crbug.com/629139#c14).
TEST_F(ThreadTest, DISABLED_DestroyWhileRunningNonJoinableIsSafe) {
  {
    Thread a("DestroyWhileRunningNonJoinableIsSafe");
    Thread::Options options;
    options.joinable = false;
    EXPECT_TRUE(a.StartWithOptions(options));
    EXPECT_TRUE(a.WaitUntilThreadStarted());
  }

  // Attempt to catch use-after-frees from the non-joinable thread in the
  // scope of this test if any.
  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
}

TEST_F(ThreadTest, StopSoon) {
  Thread a("StopSoon");
  EXPECT_TRUE(a.Start());
  EXPECT_TRUE(a.message_loop());
  EXPECT_TRUE(a.IsRunning());
  a.StopSoon();
  a.Stop();
  EXPECT_FALSE(a.message_loop());
  EXPECT_FALSE(a.IsRunning());
}

TEST_F(ThreadTest, StopTwiceNop) {
  Thread a("StopTwiceNop");
  EXPECT_TRUE(a.Start());
  EXPECT_TRUE(a.message_loop());
  EXPECT_TRUE(a.IsRunning());
  a.StopSoon();
  // Calling StopSoon() a second time should be a nop.
  a.StopSoon();
  a.Stop();
  // Same with Stop().
  a.Stop();
  EXPECT_FALSE(a.message_loop());
  EXPECT_FALSE(a.IsRunning());
  // Calling them when not running should also nop.
  a.StopSoon();
  a.Stop();
}

// TODO(gab): Enable this test in conjunction with re-enabling the sequence
// check in Thread::Stop() as part of http://crbug.com/629139.
TEST_F(ThreadTest, DISABLED_StopOnNonOwningThreadIsDeath) {
  Thread a("StopOnNonOwningThreadDeath");
  EXPECT_TRUE(a.StartAndWaitForTesting());

  Thread b("NonOwningThread");
  b.Start();
  EXPECT_DCHECK_DEATH({
    // Stopping |a| on |b| isn't allowed.
    b.task_runner()->PostTask(
        FROM_HERE, base::BindOnce(&Thread::Stop, base::Unretained(&a)));
    // Block here so the DCHECK on |b| always happens in this scope.
    base::PlatformThread::Sleep(base::TimeDelta::Max());
  });
}

TEST_F(ThreadTest, TransferOwnershipAndStop) {
  std::unique_ptr<Thread> a =
      std::make_unique<Thread>("TransferOwnershipAndStop");
  EXPECT_TRUE(a->StartAndWaitForTesting());
  EXPECT_TRUE(a->IsRunning());

  Thread b("TakingOwnershipThread");
  b.Start();

  base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
                            base::WaitableEvent::InitialState::NOT_SIGNALED);

  // a->DetachFromSequence() should allow |b| to use |a|'s Thread API.
  a->DetachFromSequence();
  b.task_runner()->PostTask(
      FROM_HERE, base::BindOnce(
                     [](std::unique_ptr<Thread> thread_to_stop,
                        base::WaitableEvent* event_to_signal) -> void {
                       thread_to_stop->Stop();
                       event_to_signal->Signal();
                     },
                     std::move(a), base::Unretained(&event)));

  event.Wait();
}

TEST_F(ThreadTest, StartTwice) {
  Thread a("StartTwice");

  EXPECT_FALSE(a.message_loop());
  EXPECT_FALSE(a.IsRunning());

  EXPECT_TRUE(a.Start());
  EXPECT_TRUE(a.message_loop());
  EXPECT_TRUE(a.IsRunning());

  a.Stop();
  EXPECT_FALSE(a.message_loop());
  EXPECT_FALSE(a.IsRunning());

  EXPECT_TRUE(a.Start());
  EXPECT_TRUE(a.message_loop());
  EXPECT_TRUE(a.IsRunning());

  a.Stop();
  EXPECT_FALSE(a.message_loop());
  EXPECT_FALSE(a.IsRunning());
}

// Intentional test-only race for otherwise untestable code, won't fix.
// https://crbug.com/634383
#if !defined(THREAD_SANITIZER)
TEST_F(ThreadTest, StartTwiceNonJoinableNotAllowed) {
  LOG(ERROR) << __FUNCTION__;
  Thread* a = new Thread("StartTwiceNonJoinable");
  // Non-joinable threads have to be leaked for now (see
  // Thread::Options::joinable for details).
  ANNOTATE_LEAKING_OBJECT_PTR(a);

  Thread::Options options;
  options.joinable = false;
  EXPECT_TRUE(a->StartWithOptions(options));
  EXPECT_TRUE(a->message_loop());
  EXPECT_TRUE(a->IsRunning());

  // Signaled when last task on |a| is processed.
  base::WaitableEvent last_task_event(
      base::WaitableEvent::ResetPolicy::AUTOMATIC,
      base::WaitableEvent::InitialState::NOT_SIGNALED);
  a->task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&base::WaitableEvent::Signal,
                                base::Unretained(&last_task_event)));

  // StopSoon() is non-blocking, Yield() to |a|, wait for last task to be
  // processed and a little more for QuitWhenIdle() to unwind before considering
  // the thread "stopped".
  a->StopSoon();
  base::PlatformThread::YieldCurrentThread();
  last_task_event.Wait();
  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));

  // This test assumes that the above was sufficient to let the thread fully
  // stop.
  ASSERT_FALSE(a->IsRunning());

  // Restarting it should not be allowed.
  EXPECT_DCHECK_DEATH(a->Start());
}
#endif

TEST_F(ThreadTest, ThreadName) {
  Thread a("ThreadName");
  EXPECT_TRUE(a.Start());
  EXPECT_EQ("ThreadName", a.thread_name());
}

TEST_F(ThreadTest, ThreadId) {
  Thread a("ThreadId0");
  Thread b("ThreadId1");
  a.Start();
  b.Start();

  // Post a task that calls GetThreadId() on the created thread.
  base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                            base::WaitableEvent::InitialState::NOT_SIGNALED);
  base::PlatformThreadId id_from_new_thread;
  a.task_runner()->PostTask(
      FROM_HERE,
      base::BindOnce(ReturnThreadId, &a, &id_from_new_thread, &event));

  // Call GetThreadId() on the current thread before calling event.Wait() so
  // that this test can find a race issue with TSAN.
  base::PlatformThreadId id_from_current_thread = a.GetThreadId();

  // Check if GetThreadId() returns consistent value in both threads.
  event.Wait();
  EXPECT_EQ(id_from_current_thread, id_from_new_thread);

  // A started thread should have a valid ID.
  EXPECT_NE(base::kInvalidThreadId, a.GetThreadId());
  EXPECT_NE(base::kInvalidThreadId, b.GetThreadId());

  // Each thread should have a different thread ID.
  EXPECT_NE(a.GetThreadId(), b.GetThreadId());
}

TEST_F(ThreadTest, ThreadIdWithRestart) {
  Thread a("ThreadIdWithRestart");
  base::PlatformThreadId previous_id = base::kInvalidThreadId;

  for (size_t i = 0; i < 16; ++i) {
    EXPECT_TRUE(a.Start());
    base::PlatformThreadId current_id = a.GetThreadId();
    EXPECT_NE(previous_id, current_id);
    previous_id = current_id;
    a.Stop();
  }
}

// Make sure Init() is called after Start() and before
// WaitUntilThreadInitialized() returns.
TEST_F(ThreadTest, SleepInsideInit) {
  SleepInsideInitThread t;
  EXPECT_FALSE(t.InitCalled());
  t.StartAndWaitForTesting();
  EXPECT_TRUE(t.InitCalled());
}

// Make sure that the destruction sequence is:
//
//  (1) Thread::CleanUp()
//  (2) MessageLoop::~MessageLoop()
//      MessageLoopCurrent::DestructionObservers called.
TEST_F(ThreadTest, CleanUp) {
  EventList captured_events;
  CapturingDestructionObserver loop_destruction_observer(&captured_events);

  {
    // Start a thread which writes its event into |captured_events|.
    CaptureToEventList t(&captured_events);
    EXPECT_TRUE(t.Start());
    EXPECT_TRUE(t.message_loop());
    EXPECT_TRUE(t.IsRunning());

    // Register an observer that writes into |captured_events| once the
    // thread's message loop is destroyed.
    t.task_runner()->PostTask(
        FROM_HERE,
        base::BindOnce(&RegisterDestructionObserver,
                       base::Unretained(&loop_destruction_observer)));

    // Upon leaving this scope, the thread is deleted.
  }

  // Check the order of events during shutdown.
  ASSERT_EQ(static_cast<size_t>(THREAD_NUM_EVENTS), captured_events.size());
  EXPECT_EQ(THREAD_EVENT_INIT, captured_events[0]);
  EXPECT_EQ(THREAD_EVENT_CLEANUP, captured_events[1]);
  EXPECT_EQ(THREAD_EVENT_MESSAGE_LOOP_DESTROYED, captured_events[2]);
}

TEST_F(ThreadTest, ThreadNotStarted) {
  Thread a("Inert");
  EXPECT_FALSE(a.task_runner());
}

TEST_F(ThreadTest, MultipleWaitUntilThreadStarted) {
  Thread a("MultipleWaitUntilThreadStarted");
  EXPECT_TRUE(a.Start());
  // It's OK to call WaitUntilThreadStarted() multiple times.
  EXPECT_TRUE(a.WaitUntilThreadStarted());
  EXPECT_TRUE(a.WaitUntilThreadStarted());
}

TEST_F(ThreadTest, FlushForTesting) {
  Thread a("FlushForTesting");

  // Flushing a non-running thread should be a no-op.
  a.FlushForTesting();

  ASSERT_TRUE(a.Start());

  // Flushing a thread with no tasks shouldn't block.
  a.FlushForTesting();

  constexpr base::TimeDelta kSleepPerTestTask =
      base::TimeDelta::FromMilliseconds(50);
  constexpr size_t kNumSleepTasks = 5;

  const base::TimeTicks ticks_before_post = base::TimeTicks::Now();

  for (size_t i = 0; i < kNumSleepTasks; ++i) {
    a.task_runner()->PostTask(
        FROM_HERE,
        base::BindOnce(&base::PlatformThread::Sleep, kSleepPerTestTask));
  }

  // All tasks should have executed, as reflected by the elapsed time.
  a.FlushForTesting();
  EXPECT_GE(base::TimeTicks::Now() - ticks_before_post,
            kNumSleepTasks * kSleepPerTestTask);

  a.Stop();

  // Flushing a stopped thread should be a no-op.
  a.FlushForTesting();
}

namespace {

// A Thread which uses a MessageLoop on the stack. It won't start a real
// underlying thread (instead its messages can be processed by a RunLoop on the
// stack).
class ExternalMessageLoopThread : public Thread {
 public:
  ExternalMessageLoopThread() : Thread("ExternalMessageLoopThread") {}

  ~ExternalMessageLoopThread() override { Stop(); }

  void InstallMessageLoop() { SetMessageLoop(&external_message_loop_); }

  void VerifyUsingExternalMessageLoop(
      bool expected_using_external_message_loop) {
    EXPECT_EQ(expected_using_external_message_loop,
              using_external_message_loop());
  }

 private:
  base::MessageLoop external_message_loop_;

  DISALLOW_COPY_AND_ASSIGN(ExternalMessageLoopThread);
};

}  // namespace

TEST_F(ThreadTest, ExternalMessageLoop) {
  ExternalMessageLoopThread a;
  EXPECT_FALSE(a.message_loop());
  EXPECT_FALSE(a.IsRunning());
  a.VerifyUsingExternalMessageLoop(false);

  a.InstallMessageLoop();
  EXPECT_TRUE(a.message_loop());
  EXPECT_TRUE(a.IsRunning());
  a.VerifyUsingExternalMessageLoop(true);

  bool ran = false;
  a.task_runner()->PostTask(
      FROM_HERE, base::BindOnce([](bool* toggled) { *toggled = true; }, &ran));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ran);

  a.Stop();
  EXPECT_FALSE(a.message_loop());
  EXPECT_FALSE(a.IsRunning());
  a.VerifyUsingExternalMessageLoop(true);

  // Confirm that running any remaining tasks posted from Stop() goes smoothly
  // (e.g. https://codereview.chromium.org/2135413003/#ps300001 crashed if
  // StopSoon() posted Thread::ThreadQuitHelper() while |run_loop_| was null).
  base::RunLoop().RunUntilIdle();
}
