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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/callback_helpers_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/callback_helpers.h
diff --git a/base/callback_helpers.h b/base/callback_helpers.h
index 6e0aee88822d85cee8d5481241ac26741629d9b3..8d622f86552a5ec622b65a88d14ecf02316a2a99 100644
--- a/base/callback_helpers.h
+++ b/base/callback_helpers.h
@@ -14,22 +14,64 @@
#ifndef BASE_CALLBACK_HELPERS_H_
#define BASE_CALLBACK_HELPERS_H_
+#include <utility>
+
+#include "base/atomicops.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
namespace base {
template <typename Signature,
internal::CopyMode copy_mode,
internal::RepeatMode repeat_mode>
-base::Callback<Signature, copy_mode, repeat_mode> ResetAndReturn(
- base::Callback<Signature, copy_mode, repeat_mode>* cb) {
- base::Callback<Signature, copy_mode, repeat_mode> ret(std::move(*cb));
+Callback<Signature, copy_mode, repeat_mode> ResetAndReturn(
+ Callback<Signature, copy_mode, repeat_mode>* cb) {
+ Callback<Signature, copy_mode, repeat_mode> ret(std::move(*cb));
DCHECK(!*cb);
return ret;
}
+namespace internal {
+
+template <typename... Args>
+class AdaptCallbackForRepeatingHelper final {
+ public:
+ explicit AdaptCallbackForRepeatingHelper(OnceCallback<void(Args...)> callback)
+ : callback_(std::move(callback)) {
+ DCHECK(callback_);
+ }
+
+ void Run(Args... args) {
+ if (subtle::NoBarrier_AtomicExchange(&has_run_, 1))
+ return;
+ DCHECK(callback_);
+ std::move(callback_).Run(std::forward<Args>(args)...);
+ }
+
+ private:
+ volatile subtle::Atomic32 has_run_ = 0;
+ base::OnceCallback<void(Args...)> callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(AdaptCallbackForRepeatingHelper);
+};
+
+} // namespace internal
+
+// Wraps the given OnceCallback into a RepeatingCallback that relays its
+// invocation to the original OnceCallback on the first invocation. The
+// following invocations are just ignored.
+template <typename... Args>
+RepeatingCallback<void(Args...)> AdaptCallbackForRepeating(
+ OnceCallback<void(Args...)> callback) {
+ using Helper = internal::AdaptCallbackForRepeatingHelper<Args...>;
+ return base::BindRepeating(&Helper::Run,
+ base::MakeUnique<Helper>(std::move(callback)));
+}
+
// ScopedClosureRunner is akin to std::unique_ptr<> for Closures. It ensures
// that the Closure is executed no matter how the current scope exits.
class BASE_EXPORT ScopedClosureRunner {
« 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