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