Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Unified Diff: base/message_loop_proxy.cc

Issue 7210053: Implementation of PostTaskAndReply() in MessageLoopProxy and BrowserThread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: don't hang browserthread. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/message_loop_proxy.cc
diff --git a/base/message_loop_proxy.cc b/base/message_loop_proxy.cc
index a38db393f6e4aa63412455d435804b608f86c682..27c1c0f784c675344ed008589c772067c0957687 100644
--- a/base/message_loop_proxy.cc
+++ b/base/message_loop_proxy.cc
@@ -4,6 +4,8 @@
#include "base/message_loop_proxy.h"
+#include "base/bind.h"
+
namespace base {
MessageLoopProxy::MessageLoopProxy() {
@@ -12,8 +14,65 @@ MessageLoopProxy::MessageLoopProxy() {
MessageLoopProxy::~MessageLoopProxy() {
}
+bool MessageLoopProxy::PostTaskAndReply(
+ const tracked_objects::Location& from_here,
+ const Closure& task,
+ const Closure& reply) {
+ internal::PostTaskAndReplyRelay* relay =
+ new internal::PostTaskAndReplyRelay(from_here, task, reply);
+ if (!PostTask(from_here, Bind(&internal::PostTaskAndReplyRelay::Run,
+ Unretained(relay)))) {
+ delete relay;
+ return false;
+ }
+
+ return true;
+}
+
void MessageLoopProxy::OnDestruct() const {
delete this;
}
+namespace internal {
+
+PostTaskAndReplyRelay::PostTaskAndReplyRelay(
+ const tracked_objects::Location& from_here,
+ const Closure& task,
+ const Closure& reply)
+ : from_here_(from_here),
+ origin_loop_(MessageLoopProxy::current()) {
+ task_ = task;
+ reply_ = reply;
+}
+
+PostTaskAndReplyRelay::~PostTaskAndReplyRelay() {
+ DCHECK(origin_loop_->BelongsToCurrentThread());
+ task_.Reset();
+ reply_.Reset();
+}
+
+void PostTaskAndReplyRelay::Run() {
+ task_.Run();
+ origin_loop_->PostTask(
+ from_here_,
+ Bind(&PostTaskAndReplyRelay::RunReplyAndSelfDestruct,
+ base::Unretained(this)));
+}
+
+void PostTaskAndReplyRelay::RunReplyAndSelfDestruct() {
+ DCHECK(origin_loop_->BelongsToCurrentThread());
+
+ // Force |task_| to be released before |reply_| is to ensure that no one
+ // accidentally depends on |task_| keeping one of its arguments alive while
+ // |reply_| is executing.
+ task_.Reset();
+
+ reply_.Run();
+
+ // Cue mission impossible theme.
+ delete this;
+}
+
+} // namespace internal
+
} // namespace base

Powered by Google App Engine
This is Rietveld 408576698