Commit 95991b19 authored by battre@chromium.org's avatar battre@chromium.org

Move PostTaskAndReplyWithStatus into task_runner_helpers.h


BUG=TBD
TEST=no


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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132527 0039d316-1c4b-4281-b951-d872f2087c98
parent 533ba2ca
......@@ -260,6 +260,7 @@
'sys_string_conversions_mac_unittest.mm',
'sys_string_conversions_unittest.cc',
'system_monitor/system_monitor_unittest.cc',
'task_runner_util_unittest.cc',
'template_util_unittest.cc',
'test/sequenced_worker_pool_owner.cc',
'test/sequenced_worker_pool_owner.h',
......
......@@ -336,6 +336,7 @@
'sys_string_conversions_win.cc',
'task_runner.cc',
'task_runner.h',
'task_runner_util.h',
'template_util.h',
'threading/non_thread_safe.h',
'threading/non_thread_safe_impl.cc',
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -8,94 +8,16 @@
#include "base/bind_helpers.h"
#include "base/file_util.h"
#include "base/message_loop_proxy.h"
#include "base/task_runner_util.h"
namespace base {
namespace {
// Helper templates to call file_util or base::PlatformFile methods
// and reply with the returned value.
//
// Typically when you have these methods:
// R DoWorkAndReturn();
// void Callback(R& result);
//
// You can pass the result of DoWorkAndReturn to the Callback by:
//
// R* result = new R;
// message_loop_proxy->PostTaskAndReply(
// from_here,
// ReturnAsParam<R>(Bind(&DoWorkAndReturn), result),
// RelayHelper(Bind(&Callback), Owned(result)));
//
// Or just use PostTaskAndReplyWithStatus helper template (see the code below).
template <typename R1, typename R2>
struct ReturnValueTranslator {
static R2 Value(const R1& value);
};
template <typename R>
struct ReturnValueTranslator<R, R> {
static R Value(const R& value) { return value; }
};
template <>
struct ReturnValueTranslator<bool, PlatformFileError> {
static PlatformFileError Value(const bool& value) {
if (value)
return PLATFORM_FILE_OK;
return PLATFORM_FILE_ERROR_FAILED;
}
};
template <typename R1, typename R2>
void ReturnAsParamAdapter(const Callback<R1(void)>& func, R2* result) {
if (!func.is_null())
*result = ReturnValueTranslator<R1, R2>::Value(func.Run());
}
template <typename R1, typename R2>
Closure ReturnAsParam(const Callback<R1(void)>& func, R2* result) {
DCHECK(result);
return Bind(&ReturnAsParamAdapter<R1, R2>, func, result);
}
template <typename R, typename A1>
void ReturnAsParamAdapter1(const Callback<R(A1)>& func, A1 a1, R* result) {
if (!func.is_null())
*result = func.Run(a1);
}
template <typename R, typename A1>
Closure ReturnAsParam(const Callback<R(A1)>& func, A1 a1, R* result) {
DCHECK(result);
return Bind(&ReturnAsParamAdapter1<R, A1>, func, a1, result);
}
template <typename R>
void ReplyAdapter(const Callback<void(R)>& callback, R* result) {
DCHECK(result);
if (!callback.is_null())
callback.Run(*result);
}
template <typename R, typename OWNED>
Closure ReplyHelper(const Callback<void(R)>& callback, OWNED result) {
return Bind(&ReplyAdapter<R>, callback, result);
}
// Putting everything together.
template <typename R1, typename R2>
bool PostTaskAndReplyWithStatus(
const scoped_refptr<MessageLoopProxy>& message_loop_proxy,
const tracked_objects::Location& from_here,
const Callback<R1(void)>& file_util_work,
const Callback<void(R2)>& callback,
R2* result) {
return message_loop_proxy->PostTaskAndReply(
from_here,
ReturnAsParam<R1>(file_util_work, result),
ReplyHelper(callback, Owned(result)));
void CallWithTranslatedParameter(const FileUtilProxy::StatusCallback& callback,
bool value) {
DCHECK(!callback.is_null());
callback.Run(value ? PLATFORM_FILE_OK : PLATFORM_FILE_ERROR_FAILED);
}
// Helper classes or routines for individual methods.
......@@ -319,10 +241,10 @@ bool FileUtilProxy::CreateTemporary(
const CreateTemporaryCallback& callback) {
CreateTemporaryHelper* helper = new CreateTemporaryHelper(message_loop_proxy);
return message_loop_proxy->PostTaskAndReply(
FROM_HERE,
Bind(&CreateTemporaryHelper::RunWork, Unretained(helper),
additional_file_flags),
Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback));
FROM_HERE,
Bind(&CreateTemporaryHelper::RunWork, Unretained(helper),
additional_file_flags),
Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback));
}
// static
......@@ -344,10 +266,10 @@ bool FileUtilProxy::GetFileInfo(
const GetFileInfoCallback& callback) {
GetFileInfoHelper* helper = new GetFileInfoHelper;
return message_loop_proxy->PostTaskAndReply(
FROM_HERE,
Bind(&GetFileInfoHelper::RunWorkForFilePath,
Unretained(helper), file_path),
Bind(&GetFileInfoHelper::Reply, Owned(helper), callback));
FROM_HERE,
Bind(&GetFileInfoHelper::RunWorkForFilePath,
Unretained(helper), file_path),
Bind(&GetFileInfoHelper::Reply, Owned(helper), callback));
}
// static
......@@ -357,10 +279,10 @@ bool FileUtilProxy::GetFileInfoFromPlatformFile(
const GetFileInfoCallback& callback) {
GetFileInfoHelper* helper = new GetFileInfoHelper;
return message_loop_proxy->PostTaskAndReply(
FROM_HERE,
Bind(&GetFileInfoHelper::RunWorkForPlatformFile,
Unretained(helper), file),
Bind(&GetFileInfoHelper::Reply, Owned(helper), callback));
FROM_HERE,
Bind(&GetFileInfoHelper::RunWorkForPlatformFile,
Unretained(helper), file),
Bind(&GetFileInfoHelper::Reply, Owned(helper), callback));
}
// static
......@@ -397,9 +319,9 @@ bool FileUtilProxy::Read(
}
ReadHelper* helper = new ReadHelper(bytes_to_read);
return message_loop_proxy->PostTaskAndReply(
FROM_HERE,
Bind(&ReadHelper::RunWork, Unretained(helper), file, offset),
Bind(&ReadHelper::Reply, Owned(helper), callback));
FROM_HERE,
Bind(&ReadHelper::RunWork, Unretained(helper), file, offset),
Bind(&ReadHelper::Reply, Owned(helper), callback));
}
// static
......@@ -415,9 +337,9 @@ bool FileUtilProxy::Write(
}
WriteHelper* helper = new WriteHelper(buffer, bytes_to_write);
return message_loop_proxy->PostTaskAndReply(
FROM_HERE,
Bind(&WriteHelper::RunWork, Unretained(helper), file, offset),
Bind(&WriteHelper::Reply, Owned(helper), callback));
FROM_HERE,
Bind(&WriteHelper::RunWork, Unretained(helper), file, offset),
Bind(&WriteHelper::Reply, Owned(helper), callback));
}
// static
......@@ -427,11 +349,12 @@ bool FileUtilProxy::Touch(
const Time& last_access_time,
const Time& last_modified_time,
const StatusCallback& callback) {
return PostTaskAndReplyWithStatus<bool>(
message_loop_proxy, FROM_HERE,
return base::PostTaskAndReplyWithResult(
message_loop_proxy,
FROM_HERE,
Bind(&TouchPlatformFile, file,
last_access_time, last_modified_time), callback,
new PlatformFileError);
last_access_time, last_modified_time),
Bind(&CallWithTranslatedParameter, callback));
}
// static
......@@ -441,12 +364,12 @@ bool FileUtilProxy::Touch(
const Time& last_access_time,
const Time& last_modified_time,
const StatusCallback& callback) {
return PostTaskAndReplyWithStatus<bool>(
message_loop_proxy, FROM_HERE,
return base::PostTaskAndReplyWithResult(
message_loop_proxy,
FROM_HERE,
Bind(&file_util::TouchFile, file_path,
last_access_time, last_modified_time),
callback,
new PlatformFileError);
Bind(&CallWithTranslatedParameter, callback));
}
// static
......@@ -455,10 +378,11 @@ bool FileUtilProxy::Truncate(
PlatformFile file,
int64 length,
const StatusCallback& callback) {
return PostTaskAndReplyWithStatus<bool>(
message_loop_proxy, FROM_HERE,
Bind(&TruncatePlatformFile, file, length), callback,
new PlatformFileError);
return base::PostTaskAndReplyWithResult(
message_loop_proxy,
FROM_HERE,
Bind(&TruncatePlatformFile, file, length),
Bind(&CallWithTranslatedParameter, callback));
}
// static
......@@ -466,10 +390,11 @@ bool FileUtilProxy::Flush(
scoped_refptr<MessageLoopProxy> message_loop_proxy,
PlatformFile file,
const StatusCallback& callback) {
return PostTaskAndReplyWithStatus<bool>(
message_loop_proxy, FROM_HERE,
Bind(&FlushPlatformFile, file), callback,
new PlatformFileError);
return base::PostTaskAndReplyWithResult(
message_loop_proxy,
FROM_HERE,
Bind(&FlushPlatformFile, file),
Bind(&CallWithTranslatedParameter, callback));
}
// static
......@@ -478,11 +403,8 @@ bool FileUtilProxy::RelayFileTask(
const tracked_objects::Location& from_here,
const FileTask& file_task,
const StatusCallback& callback) {
PlatformFileError* result = new PlatformFileError;
return message_loop_proxy->PostTaskAndReply(
from_here,
ReturnAsParam(file_task, result),
ReplyHelper(callback, Owned(result)));
return base::PostTaskAndReplyWithResult(
message_loop_proxy, from_here, file_task, callback);
}
// static
......@@ -494,9 +416,9 @@ bool FileUtilProxy::RelayCreateOrOpen(
CreateOrOpenHelper* helper = new CreateOrOpenHelper(
message_loop_proxy, close_task);
return message_loop_proxy->PostTaskAndReply(
FROM_HERE,
Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), open_task),
Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback));
FROM_HERE,
Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), open_task),
Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback));
}
// static
......@@ -505,11 +427,8 @@ bool FileUtilProxy::RelayClose(
const CloseTask& close_task,
PlatformFile file_handle,
const StatusCallback& callback) {
PlatformFileError* result = new PlatformFileError;
return message_loop_proxy->PostTaskAndReply(
FROM_HERE,
ReturnAsParam(close_task, file_handle, result),
ReplyHelper(callback, Owned(result)));
return base::PostTaskAndReplyWithResult(
message_loop_proxy, FROM_HERE, Bind(close_task, file_handle), callback);
}
} // namespace base
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_TASK_RUNNER_UTIL_H_
#define BASE_TASK_RUNNER_UTIL_H_
#pragma once
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/task_runner.h"
namespace base {
namespace internal {
// Helper class for TaskRunner::PostTaskAndReplyWithResult.
template <typename ReturnType>
void ReturnAsParamAdapter(const Callback<ReturnType(void)>& func,
ReturnType* result) {
if (!func.is_null())
*result = func.Run();
}
// Helper class for TaskRunner::PostTaskAndReplyWithResult.
template <typename ReturnType>
Closure ReturnAsParam(const Callback<ReturnType(void)>& func,
ReturnType* result) {
DCHECK(result);
return Bind(&ReturnAsParamAdapter<ReturnType>, func, result);
}
// Helper class for TaskRunner::PostTaskAndReplyWithResult.
template <typename ReturnType>
void ReplyAdapter(const Callback<void(ReturnType)>& callback,
ReturnType* result) {
DCHECK(result);
if(!callback.is_null())
callback.Run(*result);
}
// Helper class for TaskRunner::PostTaskAndReplyWithResult.
template <typename ReturnType, typename OwnedType>
Closure ReplyHelper(const Callback<void(ReturnType)>& callback,
OwnedType result) {
return Bind(&ReplyAdapter<ReturnType>, callback, result);
}
} // namespace internal
// When you have these methods
//
// R DoWorkAndReturn();
// void Callback(const R& result);
//
// and want to call them in a PostTaskAndReply kind of fashion where the
// result of DoWorkAndReturn is passed to the Callback, you can use
// PostTaskAndReplyWithResult as in this example:
//
// PostTaskAndReplyWithResult(
// target_thread_.message_loop_proxy(),
// FROM_HERE,
// Bind(&DoWorkAndReturn),
// Bind(&Callback));
template <typename ReturnType>
bool PostTaskAndReplyWithResult(
TaskRunner* task_runner,
const tracked_objects::Location& from_here,
const Callback<ReturnType(void)>& task,
const Callback<void(ReturnType)>& reply) {
ReturnType* result = new ReturnType;
return task_runner->PostTaskAndReply(
from_here,
internal::ReturnAsParam<ReturnType>(task, result),
internal::ReplyHelper(reply, Owned(result)));
}
} // namespace base
#endif // BASE_TASK_RUNNER_UTIL_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/task_runner_util.h"
#include "base/bind.h"
#include "base/message_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace {
int ReturnFourtyTwo() {
return 42;
}
void StoreValue(int* destination, int value) {
*destination = value;
}
} // namespace
TEST(TaskRunnerHelpersTest, PostAndReplyWithStatus) {
MessageLoop message_loop;
int result = 0;
PostTaskAndReplyWithResult(
message_loop.message_loop_proxy(),
FROM_HERE,
Bind(&ReturnFourtyTwo),
Bind(&StoreValue, &result));
message_loop.RunAllPending();
EXPECT_EQ(42, result);
}
} // namespace base
......@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/task_runner_util.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/declarative/rules_registry_service.h"
#include "chrome/browser/extensions/extension_system_factory.h"
......@@ -54,23 +55,22 @@ bool RulesFunction::RunImpl() {
EXTENSION_FUNCTION_VALIDATE(rules_registry_);
if (content::BrowserThread::CurrentlyOn(rules_registry_->GetOwnerThread())) {
RunImplOnCorrectThread();
SendResponseOnUIThread();
bool success = RunImplOnCorrectThread();
SendResponse(success);
} else {
content::BrowserThread::PostTaskAndReply(
rules_registry_->GetOwnerThread(), FROM_HERE,
base::Bind(base::IgnoreResult(&RulesFunction::RunImplOnCorrectThread),
this),
base::Bind(&RulesFunction::SendResponseOnUIThread, this));
scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
content::BrowserThread::GetMessageLoopProxyForThread(
rules_registry_->GetOwnerThread());
base::PostTaskAndReplyWithResult(
message_loop_proxy,
FROM_HERE,
base::Bind(&RulesFunction::RunImplOnCorrectThread, this),
base::Bind(&RulesFunction::SendResponse, this));
}
return true;
}
void RulesFunction::SendResponseOnUIThread() {
SendResponse(error_.empty());
}
bool AddRulesFunction::RunImplOnCorrectThread() {
scoped_ptr<AddRules::Params> params(AddRules::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
......
......@@ -26,9 +26,6 @@ class RulesFunction : public AsyncExtensionFunction {
protected:
scoped_refptr<RulesRegistry> rules_registry_;
private:
void SendResponseOnUIThread();
};
class AddRulesFunction : public RulesFunction {
......
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