Chromium Code Reviews| Index: third_party/WebKit/Source/wtf/MakeCancellable.h |
| diff --git a/third_party/WebKit/Source/wtf/MakeCancellable.h b/third_party/WebKit/Source/wtf/MakeCancellable.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1e7c93645e999fbe9a7118beb25c065ee38ecccd |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/wtf/MakeCancellable.h |
| @@ -0,0 +1,110 @@ |
| +// Copyright 2016 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. |
| + |
| +#ifndef WTF_MakeCancellable_h |
| +#define WTF_MakeCancellable_h |
| + |
| +#include "base/logging.h" |
| +#include "wtf/Functional.h" |
| +#include "wtf/RefCounted.h" |
| +#include "wtf/WTFExport.h" |
| +#include <memory> |
| + |
| +namespace WTF { |
| + |
| +class FunctionCanceller; |
| + |
| +namespace internal { |
| + |
| +class WTF_EXPORT FunctionCancellerImplBase : public RefCounted<FunctionCancellerImplBase> { |
| +public: |
| + virtual void cancel() = 0; |
| + |
| +protected: |
| + FunctionCancellerImplBase(); |
| + virtual ~FunctionCancellerImplBase(); |
| + friend RefCounted<FunctionCancellerImplBase>; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(FunctionCancellerImplBase); |
| +}; |
| + |
| +template <typename... Params> |
| +class FunctionCancellerImpl final : public FunctionCancellerImplBase { |
| +public: |
| + FunctionCancellerImpl(std::unique_ptr<Function<void(Params...)>> function) |
| + : m_function(std::move(function)) |
| + { |
| + DCHECK(m_function); |
| + } |
| + |
| + void runUnlessCancelled(const FunctionCanceller&, Params... params) |
|
Yuta Kitamura
2016/07/27 09:08:02
Is the first argument necessary?
tzik
2016/07/27 10:10:30
Yes, it's needed to ensure the FunctionCancellerIm
|
| + { |
| + if (m_function) |
| + (*m_function)(std::forward<Params>(params)...); |
| + } |
| + |
| + void cancel() override |
| + { |
| + m_function = nullptr; |
| + } |
| + |
| +private: |
| + ~FunctionCancellerImpl() override = default; |
| + |
| + std::unique_ptr<WTF::Function<void(Params...)>> m_function; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(FunctionCancellerImpl); |
| +}; |
| + |
| +} // namespace internal |
| + |
| +class WTF_EXPORT FunctionCanceller { |
| +public: |
| + FunctionCanceller(); |
| + explicit FunctionCanceller(PassRefPtr<internal::FunctionCancellerImplBase> cancellation); |
| + |
| + FunctionCanceller(FunctionCanceller&&); |
| + FunctionCanceller& operator=(FunctionCanceller&&); |
| + FunctionCanceller(const FunctionCanceller&) = delete; |
| + FunctionCanceller& operator=(const FunctionCanceller&) = delete; |
| + |
| + ~FunctionCanceller(); |
| + void detach(); |
| + void cancel(); |
| + |
| +private: |
| + RefPtr<internal::FunctionCancellerImplBase> m_cancellation; |
| +}; |
| + |
| +// makeCancellable wraps a WTF::Function to make cancellable function. |
| +// This function returns a tuple of a WTF::Function, and a FunctionCanceller. |
| +// An invocation of the resulting function is relayed to the original function, |
| +// unless the FunctionCanceller is alive and its cancel() is not called. |
| +// |
| +// Example: |
| +// void foo() {} |
| +// std::unique_ptr<Function<void()>> function = WTF::bind(&foo); |
| +// |
| +// std::unique_ptr<Function<void()>> wrappedFunction; |
| +// FunctionCanceller canceller; |
| +// std::tie(wrappedFunction, canceller) = makeCancellable(std::move(function)); |
| +// |
| +// (*wrappedFunction)(); // Not cancelled. foo() is called. |
| +// canceller.cancel(); |
| +// (*wrappedFunction)(); // Cancelled. foo() is not called. |
| +template <typename... Params> |
| +std::tuple<std::unique_ptr<Function<void(Params...)>>, FunctionCanceller> |
| +makeCancellable(std::unique_ptr<Function<void(Params...)>> function) |
| +{ |
| + using Impl = internal::FunctionCancellerImpl<Params...>; |
| + RefPtr<Impl> impl = adoptRef(new Impl(std::move(function))); |
| + // Keep a FunctionCanceller instance in the wrappedFunction itself, so that the target function |
| + // is destroyed when the Function instance is destroyed. |
| + std::unique_ptr<Function<void(Params...)>> wrappedFunction = bind(&Impl::runUnlessCancelled, impl, FunctionCanceller(impl)); |
| + return std::make_tuple(std::move(wrappedFunction), FunctionCanceller(std::move(impl))); |
| +} |
| + |
| +} // namespace WTF |
| + |
| +#endif // WTF_MakeCancellable_h |