| Index: base/thread_unittest.cc
|
| ===================================================================
|
| --- base/thread_unittest.cc (revision 70342)
|
| +++ base/thread_unittest.cc (working copy)
|
| @@ -1,260 +0,0 @@
|
| -// Copyright (c) 2006-2008 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/thread.h"
|
| -
|
| -#include <vector>
|
| -
|
| -#include "base/message_loop.h"
|
| -#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "testing/platform_test.h"
|
| -
|
| -using base::Thread;
|
| -
|
| -typedef PlatformTest ThreadTest;
|
| -
|
| -namespace {
|
| -
|
| -class ToggleValue : public Task {
|
| - public:
|
| - explicit ToggleValue(bool* value) : value_(value) {
|
| - ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean "
|
| - "in base/thread_unittest");
|
| - }
|
| - virtual void Run() {
|
| - *value_ = !*value_;
|
| - }
|
| - private:
|
| - bool* value_;
|
| -};
|
| -
|
| -class SleepSome : public Task {
|
| - public:
|
| - explicit SleepSome(int msec) : msec_(msec) {
|
| - }
|
| - virtual void Run() {
|
| - base::PlatformThread::Sleep(msec_);
|
| - }
|
| - private:
|
| - int msec_;
|
| -};
|
| -
|
| -class SleepInsideInitThread : public Thread {
|
| - public:
|
| - SleepInsideInitThread() : Thread("none") { init_called_ = false; }
|
| - virtual ~SleepInsideInitThread() { }
|
| -
|
| - virtual void Init() {
|
| - base::PlatformThread::Sleep(500);
|
| - init_called_ = true;
|
| - }
|
| - bool InitCalled() { return init_called_; }
|
| - private:
|
| - bool init_called_;
|
| -};
|
| -
|
| -enum ThreadEvent {
|
| - // Thread::Init() was called.
|
| - THREAD_EVENT_INIT,
|
| -
|
| - // The MessageLoop for the thread was deleted.
|
| - THREAD_EVENT_MESSAGE_LOOP_DESTROYED,
|
| -
|
| - // Thread::CleanUp() was called.
|
| - THREAD_EVENT_CLEANUP,
|
| -
|
| - // Thread::CleanUpAfterMessageLoopDestruction() was called.
|
| - THREAD_EVENT_CLEANUP_AFTER_LOOP,
|
| -};
|
| -
|
| -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) {
|
| - }
|
| -
|
| - virtual ~CaptureToEventList() {
|
| - // Must call Stop() manually to have our CleanUp() function called.
|
| - Stop();
|
| - }
|
| -
|
| - virtual void Init() {
|
| - event_list_->push_back(THREAD_EVENT_INIT);
|
| - }
|
| -
|
| - virtual void CleanUp() {
|
| - event_list_->push_back(THREAD_EVENT_CLEANUP);
|
| - }
|
| -
|
| - virtual void CleanUpAfterMessageLoopDestruction() {
|
| - event_list_->push_back(THREAD_EVENT_CLEANUP_AFTER_LOOP);
|
| - }
|
| -
|
| - private:
|
| - EventList* event_list_;
|
| -};
|
| -
|
| -// Observer that writes a value into |event_list| when a message loop has been
|
| -// destroyed.
|
| -class CapturingDestructionObserver : public MessageLoop::DestructionObserver {
|
| - public:
|
| - // |event_list| must remain valid throughout the observer's lifetime.
|
| - explicit CapturingDestructionObserver(EventList* event_list)
|
| - : event_list_(event_list) {
|
| - }
|
| -
|
| - // DestructionObserver implementation:
|
| - virtual void WillDestroyCurrentMessageLoop() {
|
| - event_list_->push_back(THREAD_EVENT_MESSAGE_LOOP_DESTROYED);
|
| - event_list_ = NULL;
|
| - }
|
| -
|
| - private:
|
| - EventList* event_list_;
|
| -};
|
| -
|
| -// Task that adds a destruction observer to the current message loop.
|
| -class RegisterDestructionObserver : public Task {
|
| - public:
|
| - explicit RegisterDestructionObserver(
|
| - MessageLoop::DestructionObserver* observer)
|
| - : observer_(observer) {
|
| - }
|
| -
|
| - virtual void Run() {
|
| - MessageLoop::current()->AddDestructionObserver(observer_);
|
| - observer_ = NULL;
|
| - }
|
| -
|
| - private:
|
| - MessageLoop::DestructionObserver* observer_;
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -TEST_F(ThreadTest, Restart) {
|
| - Thread a("Restart");
|
| - 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());
|
| - EXPECT_TRUE(a.Start());
|
| - EXPECT_TRUE(a.message_loop());
|
| - EXPECT_TRUE(a.IsRunning());
|
| - a.Stop();
|
| - EXPECT_FALSE(a.message_loop());
|
| - EXPECT_FALSE(a.IsRunning());
|
| - a.Stop();
|
| - EXPECT_FALSE(a.message_loop());
|
| - EXPECT_FALSE(a.IsRunning());
|
| -}
|
| -
|
| -TEST_F(ThreadTest, StartWithOptions_StackSize) {
|
| - Thread a("StartWithStackSize");
|
| - // Ensure that the thread can work with only 12 kb and still process a
|
| - // message.
|
| - Thread::Options options;
|
| - options.stack_size = 12*1024;
|
| - EXPECT_TRUE(a.StartWithOptions(options));
|
| - EXPECT_TRUE(a.message_loop());
|
| - EXPECT_TRUE(a.IsRunning());
|
| -
|
| - bool was_invoked = false;
|
| - a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked));
|
| -
|
| - // wait for the task to run (we could use a kernel event here
|
| - // instead to avoid busy waiting, but this is sufficient for
|
| - // testing purposes).
|
| - for (int i = 100; i >= 0 && !was_invoked; --i) {
|
| - base::PlatformThread::Sleep(10);
|
| - }
|
| - EXPECT_TRUE(was_invoked);
|
| -}
|
| -
|
| -TEST_F(ThreadTest, TwoTasks) {
|
| - bool was_invoked = false;
|
| - {
|
| - Thread a("TwoTasks");
|
| - 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.message_loop()->PostTask(FROM_HERE, new SleepSome(20));
|
| - a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked));
|
| - }
|
| - EXPECT_TRUE(was_invoked);
|
| -}
|
| -
|
| -TEST_F(ThreadTest, StopSoon) {
|
| - Thread a("StopSoon");
|
| - EXPECT_TRUE(a.Start());
|
| - EXPECT_TRUE(a.message_loop());
|
| - EXPECT_TRUE(a.IsRunning());
|
| - a.StopSoon();
|
| - a.StopSoon();
|
| - a.Stop();
|
| - EXPECT_FALSE(a.message_loop());
|
| - EXPECT_FALSE(a.IsRunning());
|
| -}
|
| -
|
| -TEST_F(ThreadTest, ThreadName) {
|
| - Thread a("ThreadName");
|
| - EXPECT_TRUE(a.Start());
|
| - EXPECT_EQ("ThreadName", a.thread_name());
|
| -}
|
| -
|
| -// Make sure we can't use a thread between Start() and Init().
|
| -TEST_F(ThreadTest, SleepInsideInit) {
|
| - SleepInsideInitThread t;
|
| - EXPECT_FALSE(t.InitCalled());
|
| - t.Start();
|
| - EXPECT_TRUE(t.InitCalled());
|
| -}
|
| -
|
| -// Make sure that the destruction sequence is:
|
| -//
|
| -// (1) Thread::CleanUp()
|
| -// (2) MessageLoop::~MessageLoop()
|
| -// MessageLoop::DestructionObservers called.
|
| -// (3) Thread::CleanUpAfterMessageLoopDestruction
|
| -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.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - new RegisterDestructionObserver(&loop_destruction_observer));
|
| -
|
| - // Upon leaving this scope, the thread is deleted.
|
| - }
|
| -
|
| - // Check the order of events during shutdown.
|
| - ASSERT_EQ(4u, 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]);
|
| - EXPECT_EQ(THREAD_EVENT_CLEANUP_AFTER_LOOP, captured_events[3]);
|
| -}
|
|
|