|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // This defines helpful methods for dealing with Callbacks.  Because Callbacks | 
|  | // are implemented using templates, with a class per callback signature, adding | 
|  | // methods to Callback<> itself is unattractive (lots of extra code gets | 
|  | // generated).  Instead, consider adding methods here. | 
|  |  | 
|  | #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 { | 
|  |  | 
|  | // Prefer std::move() over ResetAndReturn(). | 
|  | template <typename CallbackType> | 
|  | CallbackType ResetAndReturn(CallbackType* cb) { | 
|  | CallbackType 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. | 
|  | // | 
|  | // Note that this deliberately subverts the Once/Repeating paradigm of Callbacks | 
|  | // but helps ease the migration from old-style Callbacks. Avoid if possible; use | 
|  | // if necessary for migration. TODO(tzik): Remove it. https://crbug.com/730593 | 
|  | template <typename... Args> | 
|  | RepeatingCallback<void(Args...)> AdaptCallbackForRepeating( | 
|  | OnceCallback<void(Args...)> callback) { | 
|  | using Helper = internal::AdaptCallbackForRepeatingHelper<Args...>; | 
|  | return base::BindRepeating(&Helper::Run, | 
|  | std::make_unique<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 { | 
|  | public: | 
|  | ScopedClosureRunner(); | 
|  | explicit ScopedClosureRunner(OnceClosure closure); | 
|  | ~ScopedClosureRunner(); | 
|  |  | 
|  | ScopedClosureRunner(ScopedClosureRunner&& other); | 
|  |  | 
|  | // Releases the current closure if it's set and replaces it with the closure | 
|  | // from |other|. | 
|  | ScopedClosureRunner& operator=(ScopedClosureRunner&& other); | 
|  |  | 
|  | // Calls the current closure and resets it, so it wont be called again. | 
|  | void RunAndReset(); | 
|  |  | 
|  | // Replaces closure with the new one releasing the old one without calling it. | 
|  | void ReplaceClosure(OnceClosure closure); | 
|  |  | 
|  | // Releases the Closure without calling. | 
|  | OnceClosure Release() WARN_UNUSED_RESULT; | 
|  |  | 
|  | private: | 
|  | OnceClosure closure_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(ScopedClosureRunner); | 
|  | }; | 
|  |  | 
|  | }  // namespace base | 
|  |  | 
|  | #endif  // BASE_CALLBACK_HELPERS_H_ |