1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 // CancelableCallback is a wrapper around base::Callback that allows 6 // cancellation of a callback. CancelableCallback takes a reference on the 7 // wrapped callback until this object is destroyed or Reset()/Cancel() are 8 // called. 9 // 10 // NOTE: 11 // 12 // Calling CancelableCallback::Cancel() brings the object back to its natural, 13 // default-constructed state, i.e., CancelableCallback::callback() will return 14 // a null callback. 15 // 16 // THREAD-SAFETY: 17 // 18 // CancelableCallback objects must be created on, posted to, cancelled on, and 19 // destroyed on the same thread. 20 // 21 // 22 // EXAMPLE USAGE: 23 // 24 // In the following example, the test is verifying that RunIntensiveTest() 25 // Quit()s the message loop within 4 seconds. The cancelable callback is posted 26 // to the message loop, the intensive test runs, the message loop is run, 27 // then the callback is cancelled. 28 // 29 // RunLoop run_loop; 30 // 31 // void TimeoutCallback(const std::string& timeout_message) { 32 // FAIL() << timeout_message; 33 // run_loop.QuitWhenIdle(); 34 // } 35 // 36 // CancelableClosure timeout(base::Bind(&TimeoutCallback, "Test timed out.")); 37 // ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, timeout.callback(), 38 // TimeDelta::FromSeconds(4)); 39 // RunIntensiveTest(); 40 // run_loop.Run(); 41 // timeout.Cancel(); // Hopefully this is hit before the timeout callback runs. 42 // 43 44 #ifndef BASE_CANCELABLE_CALLBACK_H_ 45 #define BASE_CANCELABLE_CALLBACK_H_ 46 47 #include <utility> 48 49 #include "base/base_export.h" 50 #include "base/bind.h" 51 #include "base/callback.h" 52 #include "base/callback_internal.h" 53 #include "base/compiler_specific.h" 54 #include "base/logging.h" 55 #include "base/macros.h" 56 #include "base/memory/weak_ptr.h" 57 58 namespace base { 59 60 template <typename Sig> 61 class CancelableCallback; 62 63 template <typename... A> 64 class CancelableCallback<void(A...)> { 65 public: CancelableCallback()66 CancelableCallback() : weak_factory_(this) {} 67 68 // |callback| must not be null. CancelableCallback(const base::Callback<void (A...)> & callback)69 explicit CancelableCallback(const base::Callback<void(A...)>& callback) 70 : callback_(callback), weak_factory_(this) { 71 DCHECK(!callback.is_null()); 72 InitializeForwarder(); 73 } 74 ~CancelableCallback()75 ~CancelableCallback() {} 76 77 // Cancels and drops the reference to the wrapped callback. Cancel()78 void Cancel() { 79 weak_factory_.InvalidateWeakPtrs(); 80 forwarder_.Reset(); 81 callback_.Reset(); 82 } 83 84 // Returns true if the wrapped callback has been cancelled. IsCancelled()85 bool IsCancelled() const { 86 return callback_.is_null(); 87 } 88 89 // Sets |callback| as the closure that may be cancelled. |callback| may not 90 // be null. Outstanding and any previously wrapped callbacks are cancelled. Reset(const base::Callback<void (A...)> & callback)91 void Reset(const base::Callback<void(A...)>& callback) { 92 DCHECK(!callback.is_null()); 93 94 // Outstanding tasks (e.g., posted to a message loop) must not be called. 95 Cancel(); 96 97 // |forwarder_| is no longer valid after Cancel(), so re-bind. 98 InitializeForwarder(); 99 100 callback_ = callback; 101 } 102 103 // Returns a callback that can be disabled by calling Cancel(). callback()104 const base::Callback<void(A...)>& callback() const { 105 return forwarder_; 106 } 107 108 private: Forward(A...args)109 void Forward(A... args) const { 110 callback_.Run(std::forward<A>(args)...); 111 } 112 113 // Helper method to bind |forwarder_| using a weak pointer from 114 // |weak_factory_|. InitializeForwarder()115 void InitializeForwarder() { 116 forwarder_ = base::Bind(&CancelableCallback<void(A...)>::Forward, 117 weak_factory_.GetWeakPtr()); 118 } 119 120 // The wrapper closure. 121 base::Callback<void(A...)> forwarder_; 122 123 // The stored closure that may be cancelled. 124 base::Callback<void(A...)> callback_; 125 126 // Used to ensure Forward() is not run when this object is destroyed. 127 base::WeakPtrFactory<CancelableCallback<void(A...)>> weak_factory_; 128 129 DISALLOW_COPY_AND_ASSIGN(CancelableCallback); 130 }; 131 132 typedef CancelableCallback<void(void)> CancelableClosure; 133 134 } // namespace base 135 136 #endif // BASE_CANCELABLE_CALLBACK_H_ 137