Chromium Code Reviews| Index: base/task.cc |
| diff --git a/base/task.cc b/base/task.cc |
| index 3085d3465faaae0d2a3a68d7a89851e99d718f17..5199abaecdf3a7777cbbb51b36bce135aa2436a1 100644 |
| --- a/base/task.cc |
| +++ b/base/task.cc |
| @@ -5,6 +5,8 @@ |
| #include "base/task.h" |
| #include "base/bind.h" |
| +#include "base/message_loop.h" |
| +#include "base/message_loop_proxy.h" |
| Task::Task() { |
| } |
| @@ -20,47 +22,74 @@ CancelableTask::~CancelableTask() { |
| namespace base { |
| -ScopedTaskRunner::ScopedTaskRunner(Task* task) : task_(task) { |
| -} |
| - |
| -ScopedTaskRunner::~ScopedTaskRunner() { |
| - if (task_) { |
| - task_->Run(); |
| - delete task_; |
| - } |
| -} |
| - |
| -Task* ScopedTaskRunner::Release() { |
| - Task* tmp = task_; |
| - task_ = NULL; |
| - return tmp; |
| -} |
| - |
| namespace internal { |
| -PostTaskAndReplyRelay::PostTaskAndReplyRelay(const Closure& task, |
| - const Closure& reply) |
| - : task_(task), |
| - reply_(reply), |
| - origin_loop_(MessageLoop::Current()) { |
| +PostTaskAndReplyRelay::PostTaskAndReplyRelay( |
| + const tracked_objects::Location& from_here, |
| + const Closure& task, |
| + const Closure& reply) |
| + : from_here_(from_here), |
| + origin_loop_(MessageLoopProxy::CreateForCurrentThread()) { |
| + task_ = task; |
| + reply_ = reply; |
| } |
| PostTaskAndReplyRelay::~PostTaskAndReplyRelay() { |
| - DCHECK(origin_loop_ == MessageLoop::Current()); |
| + DCHECK(origin_loop_->BelongsToCurrentThread()); |
| } |
| void PostTaskAndReplyRelay::Run() { |
| task_.Run(); |
| origin_loop_->PostTask( |
| - base::Bind(&PostTaskAndReplyRelay::RunReplyAndSelfDestruct, |
| - base::Unretained(this))); |
| + from_here_, |
| + Bind(&PostTaskAndReplyRelay::RunReplyAndSelfDestruct, this)); |
| } |
| void PostTaskAndReplyRelay::RunReplyAndSelfDestruct() { |
| + DCHECK(origin_loop_->BelongsToCurrentThread()); |
| reply_.Run(); |
| - delete this; |
| + |
| + // Cue mission impossible theme. |
| + // |
| + // Even though PostTaskAndReplyRelay is refcounted, dropping the references |
| + // here is preferable because it eliminates the chance that other tasks can |
| + // interceed between the execution of reply_ and the destruction of the |
| + // Closures. |
| + task_.Reset(); |
| + reply_.Reset(); |
| +} |
| + |
| +void PostTaskAndReplyRelay::DoManualDestruction( |
| + const PostTaskAndReplyRelay* obj) { |
| + obj->origin_loop_->DeleteSoon(obj->from_here_, obj); |
| } |
| + |
| } // namespace internal |
| +ScopedTaskRunner::ScopedTaskRunner(Task* task) : task_(task) { |
| +} |
| + |
| +ScopedTaskRunner::~ScopedTaskRunner() { |
| + if (task_) { |
| + task_->Run(); |
| + delete task_; |
| + } |
| +} |
| + |
| +Task* ScopedTaskRunner::Release() { |
| + Task* tmp = task_; |
| + task_ = NULL; |
| + return tmp; |
| +} |
| + |
| +void PostTaskAndReply(MessageLoop* loop, |
|
willchan no longer on Chromium
2011/07/06 22:10:26
We should use MessageLoopProxy here.
awong
2011/08/15 22:07:55
New CL side-steps this issue.
|
| + const tracked_objects::Location& from_here, |
| + const Closure& task, |
| + const Closure& reply) { |
| + internal::PostTaskAndReplyRelay* relay = |
| + new internal::PostTaskAndReplyRelay(from_here, task, reply); |
| + loop->PostTask(from_here, |
| + Bind(&internal::PostTaskAndReplyRelay::Run, relay)); |
| +} |
| } // namespace base |