blob: 13cbd0c2139e10755e863bd3402a4ff4459db0e3 [file] [log] [blame]
[email protected]b77576f52011-11-24 04:12:041// 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//
[email protected]d4d57df2011-11-30 20:33:5210// NOTE:
11//
[email protected]33db3192013-10-18 13:07:0012// Calling CancelableCallback::Cancel() brings the object back to its natural,
13// default-constructed state, i.e., CancelableCallback::callback() will return
[email protected]d4d57df2011-11-30 20:33:5214// a null callback.
15//
16// THREAD-SAFETY:
[email protected]b77576f52011-11-24 04:12:0417//
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//
fdorayc5e45f62016-09-22 15:06:0729// RunLoop run_loop;
30//
[email protected]b77576f52011-11-24 04:12:0431// void TimeoutCallback(const std::string& timeout_message) {
32// FAIL() << timeout_message;
fdorayc5e45f62016-09-22 15:06:0733// run_loop.QuitWhenIdle();
[email protected]b77576f52011-11-24 04:12:0434// }
35//
[email protected]d4d57df2011-11-30 20:33:5236// CancelableClosure timeout(base::Bind(&TimeoutCallback, "Test timed out."));
fdorayc5e45f62016-09-22 15:06:0737// ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, timeout.callback(),
38// TimeDelta::FromSeconds(4));
[email protected]b77576f52011-11-24 04:12:0439// RunIntensiveTest();
fdorayc5e45f62016-09-22 15:06:0740// run_loop.Run();
[email protected]b77576f52011-11-24 04:12:0441// 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_
[email protected]b77576f52011-11-24 04:12:0446
kuznetsovsb020bcd82016-04-13 13:01:4747#include <utility>
48
[email protected]b77576f52011-11-24 04:12:0449#include "base/base_export.h"
[email protected]d4d57df2011-11-30 20:33:5250#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"
avi9b6f42932015-12-26 22:15:1455#include "base/macros.h"
[email protected]b77576f52011-11-24 04:12:0456#include "base/memory/weak_ptr.h"
57
58namespace base {
59
[email protected]d4d57df2011-11-30 20:33:5260template <typename Sig>
61class CancelableCallback;
62
ckehoe79411ab2014-11-15 06:00:5263template <typename... A>
64class CancelableCallback<void(A...)> {
[email protected]b77576f52011-11-24 04:12:0465 public:
[email protected]c9f977b2013-04-25 12:17:1566 CancelableCallback() : weak_factory_(this) {}
[email protected]b77576f52011-11-24 04:12:0467
68 // |callback| must not be null.
ckehoe79411ab2014-11-15 06:00:5269 explicit CancelableCallback(const base::Callback<void(A...)>& callback)
dmichael57c885a2015-01-14 01:38:0870 : callback_(callback), weak_factory_(this) {
[email protected]d4d57df2011-11-30 20:33:5271 DCHECK(!callback.is_null());
72 InitializeForwarder();
73 }
[email protected]b77576f52011-11-24 04:12:0474
[email protected]d4d57df2011-11-30 20:33:5275 ~CancelableCallback() {}
[email protected]b77576f52011-11-24 04:12:0476
77 // Cancels and drops the reference to the wrapped callback.
[email protected]d4d57df2011-11-30 20:33:5278 void Cancel() {
79 weak_factory_.InvalidateWeakPtrs();
80 forwarder_.Reset();
81 callback_.Reset();
82 }
[email protected]b77576f52011-11-24 04:12:0483
84 // Returns true if the wrapped callback has been cancelled.
[email protected]d4d57df2011-11-30 20:33:5285 bool IsCancelled() const {
86 return callback_.is_null();
87 }
[email protected]b77576f52011-11-24 04:12:0488
89 // Sets |callback| as the closure that may be cancelled. |callback| may not
90 // be null. Outstanding and any previously wrapped callbacks are cancelled.
ckehoe79411ab2014-11-15 06:00:5291 void Reset(const base::Callback<void(A...)>& callback) {
[email protected]d4d57df2011-11-30 20:33:5292 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 }
[email protected]b77576f52011-11-24 04:12:04102
103 // Returns a callback that can be disabled by calling Cancel().
ckehoe79411ab2014-11-15 06:00:52104 const base::Callback<void(A...)>& callback() const {
[email protected]d4d57df2011-11-30 20:33:52105 return forwarder_;
106 }
[email protected]b77576f52011-11-24 04:12:04107
108 private:
ckehoe79411ab2014-11-15 06:00:52109 void Forward(A... args) const {
kuznetsovsb020bcd82016-04-13 13:01:47110 callback_.Run(std::forward<A>(args)...);
[email protected]d4d57df2011-11-30 20:33:52111 }
[email protected]b77576f52011-11-24 04:12:04112
113 // Helper method to bind |forwarder_| using a weak pointer from
114 // |weak_factory_|.
[email protected]d4d57df2011-11-30 20:33:52115 void InitializeForwarder() {
ckehoe79411ab2014-11-15 06:00:52116 forwarder_ = base::Bind(&CancelableCallback<void(A...)>::Forward,
[email protected]d4d57df2011-11-30 20:33:52117 weak_factory_.GetWeakPtr());
118 }
[email protected]b77576f52011-11-24 04:12:04119
[email protected]b77576f52011-11-24 04:12:04120 // The wrapper closure.
ckehoe79411ab2014-11-15 06:00:52121 base::Callback<void(A...)> forwarder_;
[email protected]b77576f52011-11-24 04:12:04122
123 // The stored closure that may be cancelled.
ckehoe79411ab2014-11-15 06:00:52124 base::Callback<void(A...)> callback_;
[email protected]b77576f52011-11-24 04:12:04125
dmichael57c885a2015-01-14 01:38:08126 // Used to ensure Forward() is not run when this object is destroyed.
127 base::WeakPtrFactory<CancelableCallback<void(A...)>> weak_factory_;
128
[email protected]b77576f52011-11-24 04:12:04129 DISALLOW_COPY_AND_ASSIGN(CancelableCallback);
130};
131
[email protected]d4d57df2011-11-30 20:33:52132typedef CancelableCallback<void(void)> CancelableClosure;
133
[email protected]b77576f52011-11-24 04:12:04134} // namespace base
135
136#endif // BASE_CANCELABLE_CALLBACK_H_