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