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 // void TimeoutCallback(const std::string& timeout_message) { 30 // FAIL() << timeout_message; 31 // MessageLoop::current()->QuitWhenIdle(); 32 // } 33 // 34 // CancelableClosure timeout(base::Bind(&TimeoutCallback, "Test timed out.")); 35 // MessageLoop::current()->PostDelayedTask(FROM_HERE, timeout.callback(), 36 // 4000) // 4 seconds to run. 37 // RunIntensiveTest(); 38 // MessageLoop::current()->Run(); 39 // timeout.Cancel(); // Hopefully this is hit before the timeout callback runs. 40 // 41 42 #ifndef BASE_CANCELABLE_CALLBACK_H_ 43 #define BASE_CANCELABLE_CALLBACK_H_ 44 45 #include <utility> 46 47 #include "base/base_export.h" 48 #include "base/bind.h" 49 #include "base/callback.h" 50 #include "base/callback_internal.h" 51 #include "base/compiler_specific.h" 52 #include "base/logging.h" 53 #include "base/macros.h" 54 #include "base/memory/weak_ptr.h" 55 56 namespace base { 57 58 template <typename Sig> 59 class CancelableCallback; 60 61 template <typename... A> 62 class CancelableCallback<void(A...)> { 63 public: 64 CancelableCallback() : weak_factory_(this) {} 65 66 // |callback| must not be null. 67 explicit CancelableCallback(const base::Callback<void(A...)>& callback) 68 : callback_(callback), weak_factory_(this) { 69 DCHECK(!callback.is_null()); 70 InitializeForwarder(); 71 } 72 73 ~CancelableCallback() {} 74 75 // Cancels and drops the reference to the wrapped callback. 76 void Cancel() { 77 weak_factory_.InvalidateWeakPtrs(); 78 forwarder_.Reset(); 79 callback_.Reset(); 80 } 81 82 // Returns true if the wrapped callback has been cancelled. 83 bool IsCancelled() const { 84 return callback_.is_null(); 85 } 86 87 // Sets |callback| as the closure that may be cancelled. |callback| may not 88 // be null. Outstanding and any previously wrapped callbacks are cancelled. 89 void Reset(const base::Callback<void(A...)>& callback) { 90 DCHECK(!callback.is_null()); 91 92 // Outstanding tasks (e.g., posted to a message loop) must not be called. 93 Cancel(); 94 95 // |forwarder_| is no longer valid after Cancel(), so re-bind. 96 InitializeForwarder(); 97 98 callback_ = callback; 99 } 100 101 // Returns a callback that can be disabled by calling Cancel(). 102 const base::Callback<void(A...)>& callback() const { 103 return forwarder_; 104 } 105 106 private: 107 void Forward(A... args) const { 108 callback_.Run(std::forward<A>(args)...); 109 } 110 111 // Helper method to bind |forwarder_| using a weak pointer from 112 // |weak_factory_|. 113 void InitializeForwarder() { 114 forwarder_ = base::Bind(&CancelableCallback<void(A...)>::Forward, 115 weak_factory_.GetWeakPtr()); 116 } 117 118 // The wrapper closure. 119 base::Callback<void(A...)> forwarder_; 120 121 // The stored closure that may be cancelled. 122 base::Callback<void(A...)> callback_; 123 124 // Used to ensure Forward() is not run when this object is destroyed. 125 base::WeakPtrFactory<CancelableCallback<void(A...)>> weak_factory_; 126 127 DISALLOW_COPY_AND_ASSIGN(CancelableCallback); 128 }; 129 130 typedef CancelableCallback<void(void)> CancelableClosure; 131 132 } // namespace base 133 134 #endif // BASE_CANCELABLE_CALLBACK_H_ 135