Chromium Code Reviews| Index: third_party/WebKit/Source/wtf/Functional.h |
| diff --git a/third_party/WebKit/Source/wtf/Functional.h b/third_party/WebKit/Source/wtf/Functional.h |
| index c64bfb68cf4bed64d3a2574bcdd861b13f2b86ef..b3b5bcdcabed7fc040116b85b42b0a865fa0ffab 100644 |
| --- a/third_party/WebKit/Source/wtf/Functional.h |
| +++ b/third_party/WebKit/Source/wtf/Functional.h |
| @@ -27,6 +27,7 @@ |
| #define WTF_Functional_h |
| #include "base/bind.h" |
| +#include "base/threading/thread_checker.h" |
| #include "base/tuple.h" |
| #include "wtf/Allocator.h" |
| #include "wtf/Assertions.h" |
| @@ -155,64 +156,6 @@ UnretainedWrapper<T, CrossThreadAffinity> crossThreadUnretained(T* value) |
| return UnretainedWrapper<T, CrossThreadAffinity>(value); |
| } |
| -// A FunctionWrapper is a class template that can wrap a function pointer or a member function pointer and |
| -// provide a unified interface for calling that function. |
| -template <typename> |
| -class FunctionWrapper; |
| - |
| -// Bound static functions: |
| -template <typename R, typename... Parameters> |
| -class FunctionWrapper<R(*)(Parameters...)> { |
| - DISALLOW_NEW(); |
| -public: |
| - typedef R ResultType; |
| - static const size_t numberOfArguments = sizeof...(Parameters); |
| - |
| - explicit FunctionWrapper(R(*function)(Parameters...)) |
| - : m_function(function) |
| - { |
| - } |
| - |
| - template <typename... IncomingParameters> |
| - R operator()(IncomingParameters&&... parameters) |
| - { |
| - return m_function(std::forward<IncomingParameters>(parameters)...); |
| - } |
| - |
| -private: |
| - R(*m_function)(Parameters...); |
| -}; |
| - |
| -// Bound member functions: |
| - |
| -template <typename R, typename C, typename... Parameters> |
| -class FunctionWrapper<R(C::*)(Parameters...)> { |
| - DISALLOW_NEW(); |
| -public: |
| - typedef R ResultType; |
| - // + 1 is for |this| as an argument. |
| - static const size_t numberOfArguments = sizeof...(Parameters) + 1; |
| - |
| - explicit FunctionWrapper(R(C::*function)(Parameters...)) |
| - : m_function(function) |
| - { |
| - } |
| - |
| - template <typename Receiver, typename... IncomingParameters> |
| - R operator()(Receiver&& receiver, IncomingParameters&&... parameters) |
| - { |
| - if (base::IsWeakReceiver<typename std::decay<Receiver>::type>::value && !receiver) { |
| - return R(); |
| - } |
| - |
| - C& c = *receiver; |
| - return (c.*m_function)(std::forward<IncomingParameters>(parameters)...); |
| - } |
| - |
| -private: |
| - R(C::*m_function)(Parameters...); |
| -}; |
| - |
| template <typename T> |
| struct ParamStorageTraits { |
| typedef T StorageType; |
| @@ -266,93 +209,35 @@ T* Unwrap(const UnretainedWrapper<T, threadAffinity>& wrapped) |
| return wrapped.value(); |
| } |
| - |
| -template<typename, FunctionThreadAffinity threadAffinity = SameThreadAffinity> |
| +template<typename Signature, FunctionThreadAffinity threadAffinity = SameThreadAffinity> |
| class Function; |
| -template<FunctionThreadAffinity threadAffinity, typename R, typename... Args> |
| +template<typename R, typename... Args, FunctionThreadAffinity threadAffinity> |
| class Function<R(Args...), threadAffinity> { |
| USING_FAST_MALLOC(Function); |
| WTF_MAKE_NONCOPYABLE(Function); |
| public: |
| - virtual ~Function() { } |
| - virtual R operator()(Args... args) = 0; |
| -protected: |
| - Function() = default; |
| - void checkThread() { } |
| -}; |
| - |
| -#if ENABLE(ASSERT) |
| -template<typename R, typename... Args> |
| -class Function<R(Args...), SameThreadAffinity> { |
| - USING_FAST_MALLOC(Function); |
| - WTF_MAKE_NONCOPYABLE(Function); |
| -public: |
| - virtual ~Function() |
| - { |
| - checkThread(); |
| - } |
| - virtual R operator()(Args... args) = 0; |
| -protected: |
| - Function() |
| - : m_createdThread(currentThread()) |
| - { |
| - } |
| - |
| - void NEVER_INLINE checkThread() |
| - { |
| - // Function with SameThreadAffinity, including SameThreadClosure |
| - // created by WTF::bind() or blink::createSameThreadTask(), |
| - // must be called and destructed on the thread where it is created. |
| - // If it is intended to be used cross-thread, use |
| - // blink::threadSafeBind() or blink::createCrossThreadTask() instead. |
| - RELEASE_ASSERT(m_createdThread == currentThread()); |
| - } |
| - |
| -private: |
| - const ThreadIdentifier m_createdThread; |
| -}; |
| -#endif |
| - |
| -template <FunctionThreadAffinity threadAffinity, typename BoundParametersTuple, typename FunctionWrapper, typename UnboundRunType> |
| -class PartBoundFunctionImpl; |
| + Function(base::Callback<R(Args...)> callback) |
| + : m_callback(std::move(callback)) { } |
| -template <FunctionThreadAffinity threadAffinity, typename... BoundParameters, typename FunctionWrapper, typename ResultType, typename... UnboundParameters> |
| -class PartBoundFunctionImpl<threadAffinity, std::tuple<BoundParameters...>, FunctionWrapper, ResultType(UnboundParameters...)> final : public Function<ResultType(UnboundParameters...), threadAffinity> { |
| -public: |
| - // We would like to use StorageTraits<UnboundParameters>... with StorageTraits defined as below in order to obtain |
| - // storage traits of UnboundParameters, but unfortunately MSVC can't handle template using declarations correctly. |
| - // So, sadly, we have write down the full type signature in all places where storage traits are needed. |
| - // |
| - // template <typename T> |
| - // using StorageTraits = ParamStorageTraits<typename std::decay<T>::type>; |
| - |
| - // Note that BoundParameters can be const T&, T&& or a mix of these. |
| - explicit PartBoundFunctionImpl(FunctionWrapper functionWrapper, BoundParameters... bound) |
| - : m_functionWrapper(functionWrapper) |
| - , m_bound(std::forward<BoundParameters>(bound)...) |
| + ~Function() |
| { |
| + DCHECK(m_threadChecker.CalledOnValidThread()); |
| } |
| - ResultType operator()(UnboundParameters... unbound) override |
| + R operator()(Args... args) |
| { |
| - // What we really want to do is to call m_functionWrapper(m_bound..., unbound...), but to do that we need to |
| - // pass a list of indices to a worker function template. |
| - return callInternal(base::MakeIndexSequence<sizeof...(BoundParameters)>(), std::forward<UnboundParameters>(unbound)...); |
| + DCHECK(m_threadChecker.CalledOnValidThread()); |
| + return m_callback.Run(std::forward<Args>(args)...); |
| } |
| private: |
| - template <std::size_t... boundIndices, typename... IncomingUnboundParameters> |
| - ResultType callInternal(const base::IndexSequence<boundIndices...>&, IncomingUnboundParameters&&... unbound) |
| - { |
| - this->checkThread(); |
| - // Get each element in m_bound, unwrap them, and call the function with the desired arguments. |
| - using base::internal::Unwrap; |
| - return m_functionWrapper(Unwrap(std::get<boundIndices>(m_bound))..., std::forward<IncomingUnboundParameters>(unbound)...); |
| - } |
| - |
| - FunctionWrapper m_functionWrapper; |
| - std::tuple<typename ParamStorageTraits<typename std::decay<BoundParameters>::type>::StorageType...> m_bound; |
| + using MaybeThreadChecker = typename std::conditional< |
| + threadAffinity == SameThreadAffinity, |
| + base::ThreadChecker, |
| + base::ThreadCheckerDoNothing>::type; |
| + MaybeThreadChecker m_threadChecker; |
| + base::Callback<R(Args...)> m_callback; |
| }; |
| template <FunctionThreadAffinity threadAffinity, typename FunctionType, typename... BoundParameters> |
| @@ -363,12 +248,9 @@ std::unique_ptr<Function<base::MakeUnboundRunType<FunctionType, BoundParameters. |
| // std::tuple<> is just for carrying the bound parameters' types. Any other class template taking a type parameter |
| // pack can be used instead of std::tuple. std::tuple is used just because it's most convenient for this purpose. |
| using UnboundRunType = base::MakeUnboundRunType<FunctionType, BoundParameters...>; |
| - using BoundFunctionType = PartBoundFunctionImpl<threadAffinity, std::tuple<BoundParameters&&...>, FunctionWrapper<FunctionType>, UnboundRunType>; |
| - return wrapUnique(new BoundFunctionType(FunctionWrapper<FunctionType>(function), std::forward<BoundParameters>(boundParameters)...)); |
| + return wrapUnique(new Function<UnboundRunType, threadAffinity>(base::Bind(function, typename ParamStorageTraits<typename std::decay<BoundParameters>::type>::StorageType(std::forward<BoundParameters>(boundParameters))...))); |
|
Yuta Kitamura
2016/06/27 06:46:36
This line makes my brain cause a traffic jam... Le
tzik
2016/06/27 06:53:43
Agree. It's too long to look at a glance...
1. Yes
|
| } |
| - |
| - |
| template <typename FunctionType, typename... BoundParameters> |
| std::unique_ptr<Function<base::MakeUnboundRunType<FunctionType, BoundParameters...>, SameThreadAffinity>> bind(FunctionType function, BoundParameters&&... boundParameters) |
| { |