Index: base/cancelable_callback.h |
diff --git a/base/cancelable_callback.h b/base/cancelable_callback.h |
index 23dbe6a668c0b30191272e20cb374aa0265e8575..b432f61602c87abaa58fca3549c975b860f2cd8e 100644 |
--- a/base/cancelable_callback.h |
+++ b/base/cancelable_callback.h |
@@ -7,7 +7,13 @@ |
// wrapped callback until this object is destroyed or Reset()/Cancel() are |
// called. |
// |
-// Thread-safety notes: |
+// NOTE: |
+// |
+// Calling CancellableCallback::Cancel() brings the object back to its natural, |
+// default-constructed state, i.e., CancellableCallback::callback() will return |
+// a null callback. |
+// |
+// THREAD-SAFETY: |
// |
// CancelableCallback objects must be created on, posted to, cancelled on, and |
// destroyed on the same thread. |
@@ -25,7 +31,7 @@ |
// MessageLoop::current()->Quit(); |
// } |
// |
-// CancelableCallback timeout(base::Bind(&TimeoutCallback, "Test timed out.")); |
+// CancelableClosure timeout(base::Bind(&TimeoutCallback, "Test timed out.")); |
// MessageLoop::current()->PostDelayedTask(FROM_HERE, timeout.callback(), |
// 4000) // 4 seconds to run. |
// RunIntensiveTest(); |
@@ -37,53 +43,162 @@ |
#define BASE_CANCELABLE_CALLBACK_H_ |
#pragma once |
-#include "base/callback.h" |
#include "base/base_export.h" |
+#include "base/bind.h" |
+#include "base/callback.h" |
+#include "base/callback_internal.h" |
+#include "base/compiler_specific.h" |
+#include "base/logging.h" |
#include "base/memory/weak_ptr.h" |
namespace base { |
-class BASE_EXPORT CancelableCallback { |
+template <typename Sig> |
+class CancelableCallback; |
+ |
+template <> |
+class CancelableCallback<void(void)> { |
public: |
- CancelableCallback(); |
+ CancelableCallback() : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {} |
// |callback| must not be null. |
- explicit CancelableCallback(const base::Closure& callback); |
+ explicit CancelableCallback(const base::Callback<void(void)>& callback) |
+ : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
+ callback_(callback) { |
+ DCHECK(!callback.is_null()); |
+ InitializeForwarder(); |
+ } |
- ~CancelableCallback(); |
+ ~CancelableCallback() {} |
// Cancels and drops the reference to the wrapped callback. |
- void Cancel(); |
+ void Cancel() { |
+ weak_factory_.InvalidateWeakPtrs(); |
+ forwarder_.Reset(); |
+ callback_.Reset(); |
+ } |
// Returns true if the wrapped callback has been cancelled. |
- bool IsCancelled() const; |
+ bool IsCancelled() const { |
+ return callback_.is_null(); |
+ } |
// 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::Closure& callback); |
+ void Reset(const base::Callback<void(void)>& callback) { |
+ DCHECK(!callback.is_null()); |
+ |
+ // 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; |
+ } |
// Returns a callback that can be disabled by calling Cancel(). |
- const base::Closure& callback() const; |
+ const base::Callback<void(void)>& callback() const { |
+ return forwarder_; |
+ } |
private: |
- void RunCallback(); |
+ void Forward() { |
+ callback_.Run(); |
+ } |
// Helper method to bind |forwarder_| using a weak pointer from |
// |weak_factory_|. |
- void InitializeForwarder(); |
+ void InitializeForwarder() { |
+ forwarder_ = base::Bind(&CancelableCallback<void(void)>::Forward, |
+ weak_factory_.GetWeakPtr()); |
+ } |
- // Used to ensure RunCallback() is not run when this object is destroyed. |
- base::WeakPtrFactory<CancelableCallback> weak_factory_; |
+ // Used to ensure Forward() is not run when this object is destroyed. |
+ base::WeakPtrFactory<CancelableCallback<void(void)> > weak_factory_; |
// The wrapper closure. |
- base::Closure forwarder_; |
+ base::Callback<void(void)> forwarder_; |
// The stored closure that may be cancelled. |
- base::Closure callback_; |
+ base::Callback<void(void)> callback_; |
DISALLOW_COPY_AND_ASSIGN(CancelableCallback); |
}; |
+template <typename A1> |
+class CancelableCallback<void(A1)> { |
+ public: |
+ CancelableCallback() : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {} |
+ |
+ // |callback| must not be null. |
+ explicit CancelableCallback(const base::Callback<void(A1)>& callback) |
+ : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
+ callback_(callback) { |
+ DCHECK(!callback.is_null()); |
+ InitializeForwarder(); |
+ } |
+ |
+ ~CancelableCallback() {} |
+ |
+ // Cancels and drops the reference to the wrapped callback. |
+ void Cancel() { |
+ weak_factory_.InvalidateWeakPtrs(); |
+ forwarder_.Reset(); |
+ callback_.Reset(); |
+ } |
+ |
+ // Returns true if the wrapped callback has been cancelled. |
+ bool IsCancelled() const { |
+ return callback_.is_null(); |
+ } |
+ |
+ // 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(A1)>& callback) { |
+ DCHECK(!callback.is_null()); |
+ |
+ // 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; |
+ } |
+ |
+ // Returns a callback that can be disabled by calling Cancel(). |
+ const base::Callback<void(A1)>& callback() const { |
+ return forwarder_; |
+ } |
+ |
+ private: |
+ void Forward( |
+ typename internal::CallbackParamTraits<A1>::ForwardType a1) const { |
+ callback_.Run(a1); |
+ } |
+ |
+ // Helper method to bind |forwarder_| using a weak pointer from |
+ // |weak_factory_|. |
+ void InitializeForwarder() { |
+ forwarder_ = base::Bind(&CancelableCallback<void(A1)>::Forward, |
+ weak_factory_.GetWeakPtr()); |
+ } |
+ |
+ // Used to ensure Forward() is not run when this object is destroyed. |
+ base::WeakPtrFactory<CancelableCallback<void(A1)> > weak_factory_; |
+ |
+ // The wrapper closure. |
+ base::Callback<void(A1)> forwarder_; |
+ |
+ // The stored closure that may be cancelled. |
+ base::Callback<void(A1)> callback_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CancelableCallback); |
+}; |
+ |
+typedef CancelableCallback<void(void)> CancelableClosure; |
+ |
} // namespace base |
#endif // BASE_CANCELABLE_CALLBACK_H_ |