Commit 6e238baa authored by dcheng@chromium.org's avatar dcheng@chromium.org

Remove custom Task implementations in base.

I left a few unconverted in this one, because they made my head hurt.

BUG=none
TEST=base_unittests


Review URL: http://codereview.chromium.org/8653006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111407 0039d316-1c4b-4281-b951-d872f2087c98
parent 46142951
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/synchronization/cancellation_flag.h" #include "base/synchronization/cancellation_flag.h"
#include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/spin_wait.h" #include "base/spin_wait.h"
...@@ -22,17 +23,11 @@ namespace { ...@@ -22,17 +23,11 @@ namespace {
// Define our test class. // Define our test class.
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class CancelTask : public Task { void CancelHelper(CancellationFlag* flag) {
public:
explicit CancelTask(CancellationFlag* flag) : flag_(flag) {}
virtual void Run() {
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
ASSERT_DEBUG_DEATH(flag_->Set(), ""); ASSERT_DEBUG_DEATH(flag->Set(), "");
#endif #endif
} }
private:
CancellationFlag* flag_;
};
TEST(CancellationFlagTest, SimpleSingleThreadedTest) { TEST(CancellationFlagTest, SimpleSingleThreadedTest) {
CancellationFlag flag; CancellationFlag flag;
...@@ -61,7 +56,7 @@ TEST(CancellationFlagTest, SetOnDifferentThreadDeathTest) { ...@@ -61,7 +56,7 @@ TEST(CancellationFlagTest, SetOnDifferentThreadDeathTest) {
ASSERT_TRUE(t.IsRunning()); ASSERT_TRUE(t.IsRunning());
CancellationFlag flag; CancellationFlag flag;
t.message_loop()->PostTask(FROM_HERE, new CancelTask(&flag)); t.message_loop()->PostTask(FROM_HERE, base::Bind(&CancelHelper, &flag));
} }
} // namespace } // namespace
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#if defined(OS_WIN) #if defined(OS_WIN)
#include "base/win/object_watcher.h" #include "base/win/object_watcher.h"
#else #else
#include "base/callback.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#endif #endif
...@@ -150,7 +151,7 @@ class BASE_EXPORT WaitableEventWatcher ...@@ -150,7 +151,7 @@ class BASE_EXPORT WaitableEventWatcher
MessageLoop* message_loop_; MessageLoop* message_loop_;
scoped_refptr<Flag> cancel_flag_; scoped_refptr<Flag> cancel_flag_;
AsyncWaiter* waiter_; AsyncWaiter* waiter_;
AsyncCallbackTask* callback_task_; base::Closure callback_;
scoped_refptr<WaitableEvent::WaitableEventKernel> kernel_; scoped_refptr<WaitableEvent::WaitableEventKernel> kernel_;
#endif #endif
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "base/synchronization/waitable_event_watcher.h" #include "base/synchronization/waitable_event_watcher.h"
#include "base/bind.h"
#include "base/location.h" #include "base/location.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
...@@ -52,18 +53,17 @@ class Flag : public RefCountedThreadSafe<Flag> { ...@@ -52,18 +53,17 @@ class Flag : public RefCountedThreadSafe<Flag> {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
class AsyncWaiter : public WaitableEvent::Waiter { class AsyncWaiter : public WaitableEvent::Waiter {
public: public:
AsyncWaiter(MessageLoop* message_loop, Task* task, Flag* flag) AsyncWaiter(MessageLoop* message_loop,
const base::Closure& callback,
Flag* flag)
: message_loop_(message_loop), : message_loop_(message_loop),
cb_task_(task), callback_(callback),
flag_(flag) { } flag_(flag) { }
bool Fire(WaitableEvent* event) { bool Fire(WaitableEvent* event) {
if (flag_->value()) { // Post the callback if we haven't been cancelled.
// If the callback has been canceled, we don't enqueue the task, we just if (!flag_->value()) {
// delete it instead. message_loop_->PostTask(FROM_HERE, callback_);
delete cb_task_;
} else {
message_loop_->PostTask(FROM_HERE, cb_task_);
} }
// We are removed from the wait-list by the WaitableEvent itself. It only // We are removed from the wait-list by the WaitableEvent itself. It only
...@@ -82,47 +82,31 @@ class AsyncWaiter : public WaitableEvent::Waiter { ...@@ -82,47 +82,31 @@ class AsyncWaiter : public WaitableEvent::Waiter {
private: private:
MessageLoop *const message_loop_; MessageLoop *const message_loop_;
Task *const cb_task_; base::Closure callback_;
scoped_refptr<Flag> flag_; scoped_refptr<Flag> flag_;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// For async waits we need to make a callback in a MessageLoop thread. We do // For async waits we need to make a callback in a MessageLoop thread. We do
// this by posting this task, which calls the delegate and keeps track of when // this by posting a callback, which calls the delegate and keeps track of when
// the event is canceled. // the event is canceled.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
class AsyncCallbackTask : public Task { void AsyncCallbackHelper(Flag* flag,
public: WaitableEventWatcher::Delegate* delegate,
AsyncCallbackTask(Flag* flag, WaitableEventWatcher::Delegate* delegate, WaitableEvent* event) {
WaitableEvent* event) // Runs in MessageLoop thread.
: flag_(flag), if (!flag->value()) {
delegate_(delegate), // This is to let the WaitableEventWatcher know that the event has occured
event_(event) { // because it needs to be able to return NULL from GetWatchedObject
} flag->Set();
delegate->OnWaitableEventSignaled(event);
void Run() {
// Runs in MessageLoop thread.
if (!flag_->value()) {
// This is to let the WaitableEventWatcher know that the event has occured
// because it needs to be able to return NULL from GetWatchedObject
flag_->Set();
delegate_->OnWaitableEventSignaled(event_);
}
// We are deleted by the MessageLoop
} }
}
private:
scoped_refptr<Flag> flag_;
WaitableEventWatcher::Delegate *const delegate_;
WaitableEvent *const event_;
};
WaitableEventWatcher::WaitableEventWatcher() WaitableEventWatcher::WaitableEventWatcher()
: message_loop_(NULL), : message_loop_(NULL),
cancel_flag_(NULL), cancel_flag_(NULL),
waiter_(NULL), waiter_(NULL),
callback_task_(NULL),
event_(NULL), event_(NULL),
delegate_(NULL) { delegate_(NULL) {
} }
...@@ -143,7 +127,7 @@ bool WaitableEventWatcher::StartWatching ...@@ -143,7 +127,7 @@ bool WaitableEventWatcher::StartWatching
// A user may call StartWatching from within the callback function. In this // A user may call StartWatching from within the callback function. In this
// case, we won't know that we have finished watching, expect that the Flag // case, we won't know that we have finished watching, expect that the Flag
// will have been set in AsyncCallbackTask::Run() // will have been set in AsyncCallbackHelper().
if (cancel_flag_.get() && cancel_flag_->value()) { if (cancel_flag_.get() && cancel_flag_->value()) {
if (message_loop_) { if (message_loop_) {
message_loop_->RemoveDestructionObserver(this); message_loop_->RemoveDestructionObserver(this);
...@@ -156,7 +140,7 @@ bool WaitableEventWatcher::StartWatching ...@@ -156,7 +140,7 @@ bool WaitableEventWatcher::StartWatching
DCHECK(!cancel_flag_.get()) << "StartWatching called while still watching"; DCHECK(!cancel_flag_.get()) << "StartWatching called while still watching";
cancel_flag_ = new Flag; cancel_flag_ = new Flag;
callback_task_ = new AsyncCallbackTask(cancel_flag_, delegate, event); callback_ = base::Bind(&AsyncCallbackHelper, cancel_flag_, delegate, event);
WaitableEvent::WaitableEventKernel* kernel = event->kernel_.get(); WaitableEvent::WaitableEventKernel* kernel = event->kernel_.get();
AutoLock locked(kernel->lock_); AutoLock locked(kernel->lock_);
...@@ -170,7 +154,7 @@ bool WaitableEventWatcher::StartWatching ...@@ -170,7 +154,7 @@ bool WaitableEventWatcher::StartWatching
// No hairpinning - we can't call the delegate directly here. We have to // No hairpinning - we can't call the delegate directly here. We have to
// enqueue a task on the MessageLoop as normal. // enqueue a task on the MessageLoop as normal.
current_ml->PostTask(FROM_HERE, callback_task_); current_ml->PostTask(FROM_HERE, callback_);
return true; return true;
} }
...@@ -178,7 +162,7 @@ bool WaitableEventWatcher::StartWatching ...@@ -178,7 +162,7 @@ bool WaitableEventWatcher::StartWatching
current_ml->AddDestructionObserver(this); current_ml->AddDestructionObserver(this);
kernel_ = kernel; kernel_ = kernel;
waiter_ = new AsyncWaiter(current_ml, callback_task_, cancel_flag_); waiter_ = new AsyncWaiter(current_ml, callback_, cancel_flag_);
event->Enqueue(waiter_); event->Enqueue(waiter_);
return true; return true;
...@@ -238,7 +222,7 @@ void WaitableEventWatcher::StopWatching() { ...@@ -238,7 +222,7 @@ void WaitableEventWatcher::StopWatching() {
// have been enqueued with the MessageLoop because the waiter was never // have been enqueued with the MessageLoop because the waiter was never
// signaled) // signaled)
delete waiter_; delete waiter_;
delete callback_task_; callback_.Reset();
cancel_flag_ = NULL; cancel_flag_ = NULL;
return; return;
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "base/bind.h"
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/thread_local.h" #include "base/threading/thread_local.h"
...@@ -22,14 +23,11 @@ base::LazyInstance<base::ThreadLocalBoolean> lazy_tls_bool = ...@@ -22,14 +23,11 @@ base::LazyInstance<base::ThreadLocalBoolean> lazy_tls_bool =
} // namespace } // namespace
// This task is used to trigger the message loop to exit. // This is used to trigger the message loop to exit.
class ThreadQuitTask : public Task { void ThreadQuitHelper() {
public: MessageLoop::current()->Quit();
virtual void Run() { Thread::SetThreadWasQuitProperly(true);
MessageLoop::current()->Quit(); }
Thread::SetThreadWasQuitProperly(true);
}
};
// Used to pass data to ThreadMain. This structure is allocated on the stack // Used to pass data to ThreadMain. This structure is allocated on the stack
// from within StartWithOptions. // from within StartWithOptions.
...@@ -121,7 +119,7 @@ void Thread::StopSoon() { ...@@ -121,7 +119,7 @@ void Thread::StopSoon() {
return; return;
stopping_ = true; stopping_ = true;
message_loop_->PostTask(FROM_HERE, new ThreadQuitTask()); message_loop_->PostTask(FROM_HERE, base::Bind(&ThreadQuitHelper));
} }
void Thread::Run(MessageLoop* message_loop) { void Thread::Run(MessageLoop* message_loop) {
...@@ -165,7 +163,7 @@ void Thread::ThreadMain() { ...@@ -165,7 +163,7 @@ void Thread::ThreadMain() {
// Let the thread do extra cleanup. // Let the thread do extra cleanup.
CleanUp(); CleanUp();
// Assert that MessageLoop::Quit was called by ThreadQuitTask. // Assert that MessageLoop::Quit was called by ThreadQuitHelper.
DCHECK(GetThreadWasQuitProperly()); DCHECK(GetThreadWasQuitProperly());
// We can't receive messages anymore. // We can't receive messages anymore.
......
...@@ -182,7 +182,7 @@ class BASE_EXPORT Thread : PlatformThread::Delegate { ...@@ -182,7 +182,7 @@ class BASE_EXPORT Thread : PlatformThread::Delegate {
// The name of the thread. Used for debugging purposes. // The name of the thread. Used for debugging purposes.
std::string name_; std::string name_;
friend class ThreadQuitTask; friend void ThreadQuitHelper();
DISALLOW_COPY_AND_ASSIGN(Thread); DISALLOW_COPY_AND_ASSIGN(Thread);
}; };
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <vector> #include <vector>
#include "base/bind.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h" #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -17,29 +18,11 @@ typedef PlatformTest ThreadTest; ...@@ -17,29 +18,11 @@ typedef PlatformTest ThreadTest;
namespace { namespace {
class ToggleValue : public Task { void ToggleValue(bool* value) {
public: ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean "
explicit ToggleValue(bool* value) : value_(value) { "in base/thread_unittest");
ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean " *value = !*value;
"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 { class SleepInsideInitThread : public Thread {
public: public:
...@@ -173,7 +156,7 @@ TEST_F(ThreadTest, StartWithOptions_StackSize) { ...@@ -173,7 +156,7 @@ TEST_F(ThreadTest, StartWithOptions_StackSize) {
EXPECT_TRUE(a.IsRunning()); EXPECT_TRUE(a.IsRunning());
bool was_invoked = false; bool was_invoked = false;
a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked)); a.message_loop()->PostTask(FROM_HERE, base::Bind(&ToggleValue, &was_invoked));
// wait for the task to run (we could use a kernel event here // wait for the task to run (we could use a kernel event here
// instead to avoid busy waiting, but this is sufficient for // instead to avoid busy waiting, but this is sufficient for
...@@ -194,8 +177,10 @@ TEST_F(ThreadTest, TwoTasks) { ...@@ -194,8 +177,10 @@ TEST_F(ThreadTest, TwoTasks) {
// Test that all events are dispatched before the Thread object is // Test that all events are dispatched before the Thread object is
// destroyed. We do this by dispatching a sleep event before the // destroyed. We do this by dispatching a sleep event before the
// event that will toggle our sentinel value. // event that will toggle our sentinel value.
a.message_loop()->PostTask(FROM_HERE, new SleepSome(20)); a.message_loop()->PostTask(FROM_HERE,
a.message_loop()->PostTask(FROM_HERE, new ToggleValue(&was_invoked)); base::Bind(&base::PlatformThread::Sleep, 20));
a.message_loop()->PostTask(FROM_HERE, base::Bind(&ToggleValue,
&was_invoked));
} }
EXPECT_TRUE(was_invoked); EXPECT_TRUE(was_invoked);
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "base/threading/worker_pool.h" #include "base/threading/worker_pool.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h" #include "base/location.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/task.h" #include "base/task.h"
...@@ -21,19 +22,6 @@ namespace base { ...@@ -21,19 +22,6 @@ namespace base {
namespace { namespace {
class PostTaskTestTask : public Task {
public:
explicit PostTaskTestTask(WaitableEvent* event) : event_(event) {
}
void Run() {
event_->Signal();
}
private:
WaitableEvent* event_;
};
class PostTaskAndReplyTester class PostTaskAndReplyTester
: public base::RefCountedThreadSafe<PostTaskAndReplyTester> { : public base::RefCountedThreadSafe<PostTaskAndReplyTester> {
public: public:
...@@ -81,8 +69,14 @@ TEST_F(WorkerPoolTest, PostTask) { ...@@ -81,8 +69,14 @@ TEST_F(WorkerPoolTest, PostTask) {
WaitableEvent test_event(false, false); WaitableEvent test_event(false, false);
WaitableEvent long_test_event(false, false); WaitableEvent long_test_event(false, false);
WorkerPool::PostTask(FROM_HERE, new PostTaskTestTask(&test_event), false); WorkerPool::PostTask(FROM_HERE,
WorkerPool::PostTask(FROM_HERE, new PostTaskTestTask(&long_test_event), true); base::Bind(&WaitableEvent::Signal,
base::Unretained(&test_event)),
false);
WorkerPool::PostTask(FROM_HERE,
base::Bind(&WaitableEvent::Signal,
base::Unretained(&long_test_event)),
true);
test_event.Wait(); test_event.Wait();
long_test_event.Wait(); long_test_event.Wait();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment