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

Unified Diff: base/cancelable_callback.h

Issue 8662047: base::Bind: Implement a 1-arity CancelableCallback and use this to implement (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month 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/cancelable_callback.h
diff --git a/base/cancelable_callback.h b/base/cancelable_callback.h
index 23dbe6a668c0b30191272e20cb374aa0265e8575..2750f97e61a1e65cd648d22b4457d64be4499491 100644
--- a/base/cancelable_callback.h
+++ b/base/cancelable_callback.h
@@ -25,7 +25,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 +37,159 @@
#define BASE_CANCELABLE_CALLBACK_H_
#pragma once
+#include "base/bind.h"
#include "base/callback.h"
+#include "base/callback_internal.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
#include "base/base_export.h"
#include "base/memory/weak_ptr.h"
namespace base {
-class BASE_EXPORT CancelableCallback {
+template <typename Sig>
+class CancelableCallback;
+
+template <typename R>
+class CancelableCallback<R(void)> {
awong 2011/11/30 00:09:19 the return value should always be void shouldn't i
James Hawkins 2011/11/30 00:27:51 Done.
+ public:
+ CancelableCallback() : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {}
+
+ // |callback| must not be null.
+ explicit CancelableCallback(const base::Callback<R(void)>& callback)
+ : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
awong 2011/11/30 00:09:19 Can we pull the common code out into a non-templat
James Hawkins 2011/11/30 00:27:51 Per off-line there's not any code that doesn't tou
awong 2011/11/30 00:35:06 I'm not sure. I just would really like to avoid h
+ callback_(callback) {
+ DCHECK(!callback.is_null());
+ InitializeForwarder();
+ }
+
+ ~CancelableCallback() {}
+
+ // Cancels and drops the reference to the wrapped callback.
+ void Cancel() {
+ weak_factory_.InvalidateWeakPtrs();
+ 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<R(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::Callback<R(void)>& callback() const {
+ return forwarder_;
+ }
+
+ private:
+ R RunCallback() {
+ return callback_.Run();
+ }
+
+ // Helper method to bind |forwarder_| using a weak pointer from
+ // |weak_factory_|.
+ void InitializeForwarder() {
+ forwarder_ = base::Bind(&CancelableCallback<R(void)>::RunCallback,
+ weak_factory_.GetWeakPtr());
+ }
+
+ // Used to ensure RunCallback() is not run when this object is destroyed.
+ base::WeakPtrFactory<CancelableCallback<R(void)> > weak_factory_;
+
+ // The wrapper closure.
+ base::Callback<R(void)> forwarder_;
+
+ // The stored closure that may be cancelled.
+ base::Callback<R(void)> callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(CancelableCallback);
+};
+
+template <typename R, typename A1>
+class CancelableCallback<R(A1)> {
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<R(A1)>& 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();
+ 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<R(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::Closure& callback() const;
+ const base::Callback<R(A1)>& callback() const {
+ return forwarder_;
+ }
private:
- void RunCallback();
+ R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1) const {
+ return callback_.Run(a1);
+ }
// Helper method to bind |forwarder_| using a weak pointer from
// |weak_factory_|.
- void InitializeForwarder();
+ void InitializeForwarder() {
+ forwarder_ = base::Bind(&CancelableCallback<R(A1)>::Run,
+ weak_factory_.GetWeakPtr());
+ }
// Used to ensure RunCallback() is not run when this object is destroyed.
- base::WeakPtrFactory<CancelableCallback> weak_factory_;
+ base::WeakPtrFactory<CancelableCallback<R(A1)> > weak_factory_;
// The wrapper closure.
- base::Closure forwarder_;
+ base::Callback<R(A1)> forwarder_;
// The stored closure that may be cancelled.
- base::Closure callback_;
+ base::Callback<R(A1)> callback_;
DISALLOW_COPY_AND_ASSIGN(CancelableCallback);
};
+typedef CancelableCallback<void(void)> CancelableClosure;
+
} // namespace base
#endif // BASE_CANCELABLE_CALLBACK_H_

Powered by Google App Engine
This is Rietveld 408576698