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

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: Comment fixes. 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
« no previous file with comments | « base/base.gypi ('k') | base/cancelable_callback.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_
« no previous file with comments | « base/base.gypi ('k') | base/cancelable_callback.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698