Commit 67b070ec authored by tzik's avatar tzik Committed by Commit Bot

Introduce CancelableOnceCallback

This CL refactors CancelbaleCallback into CancelableRepeatingCallback
and CancelableOnceCallback for OnceCallback support.

Change-Id: I40a3079bae598d440e84a737b7f7082a2c5e44bf
Reviewed-on: https://chromium-review.googlesource.com/737399
Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#512795}
parent e4c44cc2
......@@ -56,28 +56,24 @@
#include "base/memory/weak_ptr.h"
namespace base {
namespace internal {
template <typename Sig>
class CancelableCallback;
template <typename... A>
class CancelableCallback<void(A...)> {
template <typename CallbackType>
class CancelableCallbackImpl {
public:
CancelableCallback() : weak_factory_(this) {}
CancelableCallbackImpl() : weak_ptr_factory_(this) {}
// |callback| must not be null.
explicit CancelableCallback(const base::Callback<void(A...)>& callback)
: callback_(callback), weak_factory_(this) {
DCHECK(!callback.is_null());
InitializeForwarder();
explicit CancelableCallbackImpl(CallbackType callback)
: callback_(std::move(callback)), weak_ptr_factory_(this) {
DCHECK(callback_);
}
~CancelableCallback() {}
~CancelableCallbackImpl() = default;
// Cancels and drops the reference to the wrapped callback.
void Cancel() {
weak_factory_.InvalidateWeakPtrs();
forwarder_.Reset();
weak_ptr_factory_.InvalidateWeakPtrs();
callback_.Reset();
}
......@@ -88,48 +84,72 @@ class CancelableCallback<void(A...)> {
// Sets |callback| as the closure that may be cancelled. |callback| may not
// be null. Outstanding and any previously wrapped callbacks are cancelled.
void Reset(const base::Callback<void(A...)>& callback) {
DCHECK(!callback.is_null());
void Reset(CallbackType callback) {
DCHECK(callback);
// Outstanding tasks (e.g., posted to a message loop) must not be called.
Cancel();
// |forwarder_| is no longer valid after Cancel(), so re-bind.
InitializeForwarder();
callback_ = callback;
callback_ = std::move(callback);
}
// Returns a callback that can be disabled by calling Cancel().
const base::Callback<void(A...)>& callback() const {
return forwarder_;
CallbackType callback() const {
if (!callback_)
return CallbackType();
CallbackType forwarder;
MakeForwarder(&forwarder);
return forwarder;
}
private:
void Forward(A... args) const {
callback_.Run(std::forward<A>(args)...);
template <typename... Args>
void MakeForwarder(RepeatingCallback<void(Args...)>* out) const {
using ForwarderType = void (CancelableCallbackImpl::*)(Args...);
ForwarderType forwarder = &CancelableCallbackImpl::ForwardRepeating;
*out = BindRepeating(forwarder, weak_ptr_factory_.GetWeakPtr());
}
// Helper method to bind |forwarder_| using a weak pointer from
// |weak_factory_|.
void InitializeForwarder() {
forwarder_ = base::Bind(&CancelableCallback<void(A...)>::Forward,
weak_factory_.GetWeakPtr());
template <typename... Args>
void MakeForwarder(OnceCallback<void(Args...)>* out) const {
using ForwarderType = void (CancelableCallbackImpl::*)(Args...);
ForwarderType forwarder = &CancelableCallbackImpl::ForwardOnce;
*out = BindOnce(forwarder, weak_ptr_factory_.GetWeakPtr());
}
// The wrapper closure.
base::Callback<void(A...)> forwarder_;
template <typename... Args>
void ForwardRepeating(Args... args) {
callback_.Run(std::forward<Args>(args)...);
}
// The stored closure that may be cancelled.
base::Callback<void(A...)> callback_;
template <typename... Args>
void ForwardOnce(Args... args) {
weak_ptr_factory_.InvalidateWeakPtrs();
std::move(callback_).Run(std::forward<Args>(args)...);
}
// Used to ensure Forward() is not run when this object is destroyed.
base::WeakPtrFactory<CancelableCallback<void(A...)>> weak_factory_;
// The stored closure that may be cancelled.
CallbackType callback_;
mutable base::WeakPtrFactory<CancelableCallbackImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CancelableCallback);
DISALLOW_COPY_AND_ASSIGN(CancelableCallbackImpl);
};
typedef CancelableCallback<void(void)> CancelableClosure;
} // namespace internal
// Consider using base::WeakPtr directly instead of base::CancelableCallback for
// the task cancellation.
template <typename Signature>
using CancelableOnceCallback =
internal::CancelableCallbackImpl<OnceCallback<Signature>>;
using CancelableOnceClosure = CancelableOnceCallback<void()>;
template <typename Signature>
using CancelableRepeatingCallback =
internal::CancelableCallbackImpl<RepeatingCallback<Signature>>;
using CancelableRepeatingClosure = CancelableOnceCallback<void()>;
template <typename Signature>
using CancelableCallback = CancelableRepeatingCallback<Signature>;
using CancelableClosure = CancelableCallback<void()>;
} // namespace base
......
......@@ -297,8 +297,7 @@ void DevToolsAndroidBridge::RequestDeviceCount(
const base::Callback<void(int)>& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (device_count_listeners_.empty() ||
!callback.Equals(device_count_callback_.callback()))
if (device_count_listeners_.empty() || callback.IsCancelled())
return;
UsbDeviceProvider::CountDevices(callback);
......
......@@ -21,7 +21,7 @@ void CancelableClosureHolder::Cancel() {
cancelable_callback_.Reset(callback_);
}
const base::Closure& CancelableClosureHolder::GetCallback() const {
base::Closure CancelableClosureHolder::GetCallback() const {
DCHECK(!callback_.is_null());
return cancelable_callback_.callback();
}
......
......@@ -27,7 +27,7 @@ class CancelableClosureHolder {
// Returns a callback that will be disabled by calling Cancel(). Callback
// must have been set using Reset() before calling this function.
const base::Closure& GetCallback() const;
base::Closure GetCallback() const;
private:
base::Closure callback_;
......
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