#include "base/threading/post_task_and_reply_impl.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/message_loop_proxy.h"
namespace base {
namespace {
class PostTaskAndReplyRelay {
public:
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() {
DCHECK(origin_loop_->BelongsToCurrentThread());
task_.Reset();
reply_.Reset();
}
void Run() {
task_.Run();
origin_loop_->PostTask(
from_here_,
Bind(&PostTaskAndReplyRelay::RunReplyAndSelfDestruct,
base::Unretained(this)));
}
private:
void RunReplyAndSelfDestruct() {
DCHECK(origin_loop_->BelongsToCurrentThread());
task_.Reset();
reply_.Run();
delete this;
}
tracked_objects::Location from_here_;
scoped_refptr<MessageLoopProxy> origin_loop_;
Closure reply_;
Closure task_;
};
}
namespace internal {
bool PostTaskAndReplyImpl::PostTaskAndReply(
const tracked_objects::Location& from_here,
const Closure& task,
const Closure& reply) {
PostTaskAndReplyRelay* relay =
new PostTaskAndReplyRelay(from_here, task, reply);
if (!PostTask(from_here, Bind(&PostTaskAndReplyRelay::Run,
Unretained(relay)))) {
delete relay;
return false;
}
return true;
}
}
}