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 |