• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2011
2 // Google Inc. All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //    * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //    * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //    * Neither the name of Google Inc. nor the name Chromium Embedded
15 // Framework nor the names of its contributors may be used to endorse
16 // or promote products derived from this software without specific prior
17 // written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // CancelableCallback is a wrapper around base::Callback that allows
32 // cancellation of a callback. CancelableCallback takes a reference on the
33 // wrapped callback until this object is destroyed or Reset()/Cancel() are
34 // called.
35 //
36 // NOTE:
37 //
38 // Calling CancelableCallback::Cancel() brings the object back to its natural,
39 // default-constructed state, i.e., CancelableCallback::callback() will return
40 // a null callback.
41 //
42 // THREAD-SAFETY:
43 //
44 // CancelableCallback objects must be created on, posted to, cancelled on, and
45 // destroyed on the same thread.
46 //
47 //
48 // EXAMPLE USAGE:
49 //
50 // In the following example, the test is verifying that RunIntensiveTest()
51 // Quit()s the message loop within 4 seconds. The cancelable callback is posted
52 // to the message loop, the intensive test runs, the message loop is run,
53 // then the callback is cancelled.
54 //
55 // RunLoop run_loop;
56 //
57 // void TimeoutCallback(const std::string& timeout_message) {
58 //   FAIL() << timeout_message;
59 //   run_loop.QuitWhenIdle();
60 // }
61 //
62 // CancelableOnceClosure timeout(
63 //     base::BindOnce(&TimeoutCallback, "Test timed out."));
64 // ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, timeout.callback(),
65 //                                                TimeDelta::FromSeconds(4));
66 // RunIntensiveTest();
67 // run_loop.Run();
68 // timeout.Cancel();  // Hopefully this is hit before the timeout callback runs.
69 
70 #ifndef CEF_INCLUDE_BASE_CEF_CANCELABLE_CALLBACK_H_
71 #define CEF_INCLUDE_BASE_CEF_CANCELABLE_CALLBACK_H_
72 #pragma once
73 
74 #if defined(USING_CHROMIUM_INCLUDES)
75 // When building CEF include the Chromium header directly.
76 #include "base/cancelable_callback.h"
77 #else  // !USING_CHROMIUM_INCLUDES
78 // The following is substantially similar to the Chromium implementation.
79 // If the Chromium implementation diverges the below implementation should be
80 // updated to match.
81 
82 #include <utility>
83 
84 #include "include/base/cef_bind.h"
85 #include "include/base/cef_callback.h"
86 #include "include/base/cef_compiler_specific.h"
87 #include "include/base/cef_logging.h"
88 #include "include/base/cef_weak_ptr.h"
89 #include "include/base/internal/cef_callback_internal.h"
90 
91 namespace base {
92 namespace internal {
93 
94 template <typename CallbackType>
95 class CancelableCallbackImpl {
96  public:
97   CancelableCallbackImpl() = default;
98   CancelableCallbackImpl(const CancelableCallbackImpl&) = delete;
99   CancelableCallbackImpl& operator=(const CancelableCallbackImpl&) = delete;
100 
101   // |callback| must not be null.
CancelableCallbackImpl(CallbackType callback)102   explicit CancelableCallbackImpl(CallbackType callback)
103       : callback_(std::move(callback)) {
104     DCHECK(callback_);
105   }
106 
107   ~CancelableCallbackImpl() = default;
108 
109   // Cancels and drops the reference to the wrapped callback.
Cancel()110   void Cancel() {
111     weak_ptr_factory_.InvalidateWeakPtrs();
112     callback_.Reset();
113   }
114 
115   // Returns true if the wrapped callback has been cancelled.
IsCancelled()116   bool IsCancelled() const { return callback_.is_null(); }
117 
118   // Sets |callback| as the closure that may be cancelled. |callback| may not
119   // be null. Outstanding and any previously wrapped callbacks are cancelled.
Reset(CallbackType callback)120   void Reset(CallbackType callback) {
121     DCHECK(callback);
122     // Outstanding tasks (e.g., posted to a message loop) must not be called.
123     Cancel();
124     callback_ = std::move(callback);
125   }
126 
127   // Returns a callback that can be disabled by calling Cancel().
callback()128   CallbackType callback() const {
129     if (!callback_)
130       return CallbackType();
131     CallbackType forwarder;
132     MakeForwarder(&forwarder);
133     return forwarder;
134   }
135 
136  private:
137   template <typename... Args>
MakeForwarder(RepeatingCallback<void (Args...)> * out)138   void MakeForwarder(RepeatingCallback<void(Args...)>* out) const {
139     using ForwarderType = void (CancelableCallbackImpl::*)(Args...);
140     ForwarderType forwarder = &CancelableCallbackImpl::ForwardRepeating;
141     *out = BindRepeating(forwarder, weak_ptr_factory_.GetWeakPtr());
142   }
143 
144   template <typename... Args>
MakeForwarder(OnceCallback<void (Args...)> * out)145   void MakeForwarder(OnceCallback<void(Args...)>* out) const {
146     using ForwarderType = void (CancelableCallbackImpl::*)(Args...);
147     ForwarderType forwarder = &CancelableCallbackImpl::ForwardOnce;
148     *out = BindOnce(forwarder, weak_ptr_factory_.GetWeakPtr());
149   }
150 
151   template <typename... Args>
ForwardRepeating(Args...args)152   void ForwardRepeating(Args... args) {
153     callback_.Run(std::forward<Args>(args)...);
154   }
155 
156   template <typename... Args>
ForwardOnce(Args...args)157   void ForwardOnce(Args... args) {
158     weak_ptr_factory_.InvalidateWeakPtrs();
159     std::move(callback_).Run(std::forward<Args>(args)...);
160   }
161 
162   // The stored closure that may be cancelled.
163   CallbackType callback_;
164   mutable base::WeakPtrFactory<CancelableCallbackImpl> weak_ptr_factory_{this};
165 };
166 
167 }  // namespace internal
168 
169 // Consider using base::WeakPtr directly instead of base::CancelableCallback for
170 // the task cancellation.
171 template <typename Signature>
172 using CancelableOnceCallback =
173     internal::CancelableCallbackImpl<OnceCallback<Signature>>;
174 using CancelableOnceClosure = CancelableOnceCallback<void()>;
175 
176 template <typename Signature>
177 using CancelableRepeatingCallback =
178     internal::CancelableCallbackImpl<RepeatingCallback<Signature>>;
179 using CancelableRepeatingClosure = CancelableRepeatingCallback<void()>;
180 
181 }  // namespace base
182 
183 #endif  // !USING_CHROMIUM_INCLUDES
184 
185 #endif  // CEF_INCLUDE_BASE_CEF_CANCELABLE_CALLBACK_H_
186