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 |