Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: base/callback_helpers.h

Issue 2820993002: Introduce base::IgnoreReuse() to wrap OnceCallback into RepeatingCallback (Closed)
Patch Set: fix Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/callback_helpers_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This defines helpful methods for dealing with Callbacks. Because Callbacks 5 // This defines helpful methods for dealing with Callbacks. Because Callbacks
6 // are implemented using templates, with a class per callback signature, adding 6 // are implemented using templates, with a class per callback signature, adding
7 // methods to Callback<> itself is unattractive (lots of extra code gets 7 // methods to Callback<> itself is unattractive (lots of extra code gets
8 // generated). Instead, consider adding methods here. 8 // generated). Instead, consider adding methods here.
9 // 9 //
10 // ResetAndReturn(&cb) is like cb.Reset() but allows executing a callback (via a 10 // ResetAndReturn(&cb) is like cb.Reset() but allows executing a callback (via a
11 // move or copy) after the original callback is Reset(). This can be handy if 11 // move or copy) after the original callback is Reset(). This can be handy if
12 // Run() reads/writes the variable holding the Callback. 12 // Run() reads/writes the variable holding the Callback.
13 13
14 #ifndef BASE_CALLBACK_HELPERS_H_ 14 #ifndef BASE_CALLBACK_HELPERS_H_
15 #define BASE_CALLBACK_HELPERS_H_ 15 #define BASE_CALLBACK_HELPERS_H_
16 16
17 #include <utility>
18
19 #include "base/atomicops.h"
20 #include "base/bind.h"
17 #include "base/callback.h" 21 #include "base/callback.h"
18 #include "base/compiler_specific.h" 22 #include "base/compiler_specific.h"
19 #include "base/macros.h" 23 #include "base/macros.h"
24 #include "base/memory/ptr_util.h"
20 25
21 namespace base { 26 namespace base {
22 27
23 template <typename Signature, 28 template <typename Signature,
24 internal::CopyMode copy_mode, 29 internal::CopyMode copy_mode,
25 internal::RepeatMode repeat_mode> 30 internal::RepeatMode repeat_mode>
26 base::Callback<Signature, copy_mode, repeat_mode> ResetAndReturn( 31 Callback<Signature, copy_mode, repeat_mode> ResetAndReturn(
27 base::Callback<Signature, copy_mode, repeat_mode>* cb) { 32 Callback<Signature, copy_mode, repeat_mode>* cb) {
28 base::Callback<Signature, copy_mode, repeat_mode> ret(std::move(*cb)); 33 Callback<Signature, copy_mode, repeat_mode> ret(std::move(*cb));
29 DCHECK(!*cb); 34 DCHECK(!*cb);
30 return ret; 35 return ret;
31 } 36 }
32 37
38 namespace internal {
39
40 template <typename... Args>
41 class AdaptCallbackForRepeatingHelper final {
42 public:
43 explicit AdaptCallbackForRepeatingHelper(OnceCallback<void(Args...)> callback)
44 : callback_(std::move(callback)) {
45 DCHECK(callback_);
46 }
47
48 void Run(Args... args) {
49 if (subtle::NoBarrier_AtomicExchange(&has_run_, 1))
50 return;
51 DCHECK(callback_);
52 std::move(callback_).Run(std::forward<Args>(args)...);
53 }
54
55 private:
56 volatile subtle::Atomic32 has_run_ = 0;
57 base::OnceCallback<void(Args...)> callback_;
58
59 DISALLOW_COPY_AND_ASSIGN(AdaptCallbackForRepeatingHelper);
60 };
61
62 } // namespace internal
63
64 // Wraps the given OnceCallback into a RepeatingCallback that relays its
65 // invocation to the original OnceCallback on the first invocation. The
66 // following invocations are just ignored.
67 template <typename... Args>
68 RepeatingCallback<void(Args...)> AdaptCallbackForRepeating(
69 OnceCallback<void(Args...)> callback) {
70 using Helper = internal::AdaptCallbackForRepeatingHelper<Args...>;
71 return base::BindRepeating(&Helper::Run,
72 base::MakeUnique<Helper>(std::move(callback)));
73 }
74
33 // ScopedClosureRunner is akin to std::unique_ptr<> for Closures. It ensures 75 // ScopedClosureRunner is akin to std::unique_ptr<> for Closures. It ensures
34 // that the Closure is executed no matter how the current scope exits. 76 // that the Closure is executed no matter how the current scope exits.
35 class BASE_EXPORT ScopedClosureRunner { 77 class BASE_EXPORT ScopedClosureRunner {
36 public: 78 public:
37 ScopedClosureRunner(); 79 ScopedClosureRunner();
38 explicit ScopedClosureRunner(const Closure& closure); 80 explicit ScopedClosureRunner(const Closure& closure);
39 ~ScopedClosureRunner(); 81 ~ScopedClosureRunner();
40 82
41 ScopedClosureRunner(ScopedClosureRunner&& other); 83 ScopedClosureRunner(ScopedClosureRunner&& other);
42 84
(...skipping 12 matching lines...) Expand all
55 97
56 private: 98 private:
57 Closure closure_; 99 Closure closure_;
58 100
59 DISALLOW_COPY_AND_ASSIGN(ScopedClosureRunner); 101 DISALLOW_COPY_AND_ASSIGN(ScopedClosureRunner);
60 }; 102 };
61 103
62 } // namespace base 104 } // namespace base
63 105
64 #endif // BASE_CALLBACK_HELPERS_H_ 106 #endif // BASE_CALLBACK_HELPERS_H_
OLDNEW
« no previous file with comments | « no previous file | base/callback_helpers_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698