Changeset 245024 in webkit


Ignore:
Timestamp:
May 7, 2019 12:54:00 PM (5 years ago)
Author:
achristensen@apple.com
Message:

Add a release assertion that Functions can only be constructed from non-null CompletionHandlers
https://bugs.webkit.org/show_bug.cgi?id=197641

Reviewed by Chris Dumez.

This will help us find the cause of rdar://problem/48679972 by seeing the crash when the Function is dispatched,
not when it's called with no interesting stack trace. I manually verified this assertion is hit in such a case.
We should also have no legitimate use of creating a Function out of a null CompletionHandler then never calling it.

  • wtf/CompletionHandler.h:

(WTF::Detail::CallableWrapper<CompletionHandler<Out):

  • wtf/Function.h:

(WTF::Detail::CallableWrapperBase::~CallableWrapperBase):
(WTF::Detail::CallableWrapper::CallableWrapper):
(WTF::Function<Out):

Location:
trunk/Source/WTF
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r244994 r245024  
     12019-05-07  Alex Christensen  <achristensen@webkit.org>
     2
     3        Add a release assertion that Functions can only be constructed from non-null CompletionHandlers
     4        https://bugs.webkit.org/show_bug.cgi?id=197641
     5
     6        Reviewed by Chris Dumez.
     7
     8        This will help us find the cause of rdar://problem/48679972 by seeing the crash when the Function is dispatched,
     9        not when it's called with no interesting stack trace.  I manually verified this assertion is hit in such a case.
     10        We should also have no legitimate use of creating a Function out of a null CompletionHandler then never calling it.
     11
     12        * wtf/CompletionHandler.h:
     13        (WTF::Detail::CallableWrapper<CompletionHandler<Out):
     14        * wtf/Function.h:
     15        (WTF::Detail::CallableWrapperBase::~CallableWrapperBase):
     16        (WTF::Detail::CallableWrapper::CallableWrapper):
     17        (WTF::Function<Out):
     18
    1192019-05-06  Christopher Reid  <chris.reid@sony.com>
    220
  • trunk/Source/WTF/wtf/CompletionHandler.h

    r234332 r245024  
    6464};
    6565
     66namespace Detail {
     67
     68template<typename Out, typename... In>
     69class CallableWrapper<CompletionHandler<Out(In...)>, Out, In...> : public CallableWrapperBase<Out, In...> {
     70public:
     71    explicit CallableWrapper(CompletionHandler<Out(In...)>&& completionHandler)
     72        : m_completionHandler(WTFMove(completionHandler))
     73    {
     74        RELEASE_ASSERT(m_completionHandler);
     75    }
     76    Out call(In... in) final { return m_completionHandler(std::forward<In>(in)...); }
     77private:
     78    CompletionHandler<Out(In...)> m_completionHandler;
     79};
     80
     81} // namespace Detail
     82
    6683class CompletionHandlerCallingScope {
    6784public:
  • trunk/Source/WTF/wtf/Function.h

    r241183 r245024  
    3131namespace WTF {
    3232
     33namespace Detail {
     34
     35template<typename Out, typename... In>
     36class CallableWrapperBase {
     37    WTF_MAKE_FAST_ALLOCATED;
     38public:
     39    virtual ~CallableWrapperBase() { }
     40    virtual Out call(In...) = 0;
     41};
     42
     43template<typename, typename, typename...> class CallableWrapper;
     44
     45template<typename CallableType, typename Out, typename... In>
     46class CallableWrapper : public CallableWrapperBase<Out, In...> {
     47public:
     48    explicit CallableWrapper(CallableType&& callable)
     49        : m_callable(WTFMove(callable)) { }
     50    CallableWrapper(const CallableWrapper&) = delete;
     51    CallableWrapper& operator=(const CallableWrapper&) = delete;
     52    Out call(In... in) final { return m_callable(std::forward<In>(in)...); }
     53private:
     54    CallableType m_callable;
     55};
     56
     57} // namespace Detail
     58
    3359template<typename> class Function;
    3460
     
    4268    template<typename CallableType, class = typename std::enable_if<!(std::is_pointer<CallableType>::value && std::is_function<typename std::remove_pointer<CallableType>::type>::value) && std::is_rvalue_reference<CallableType&&>::value>::type>
    4369    Function(CallableType&& callable)
    44         : m_callableWrapper(std::make_unique<CallableWrapper<CallableType>>(WTFMove(callable)))
    45     {
    46     }
     70        : m_callableWrapper(std::make_unique<Detail::CallableWrapper<CallableType, Out, In...>>(WTFMove(callable))) { }
    4771
    4872    template<typename FunctionType, class = typename std::enable_if<std::is_pointer<FunctionType>::value && std::is_function<typename std::remove_pointer<FunctionType>::type>::value>::type>
    4973    Function(FunctionType f)
    50         : m_callableWrapper(std::make_unique<CallableWrapper<FunctionType>>(WTFMove(f)))
    51     {
    52     }
     74        : m_callableWrapper(std::make_unique<Detail::CallableWrapper<FunctionType, Out, In...>>(WTFMove(f))) { }
    5375
    5476    Out operator()(In... in) const
     
    6385    Function& operator=(CallableType&& callable)
    6486    {
    65         m_callableWrapper = std::make_unique<CallableWrapper<CallableType>>(WTFMove(callable));
     87        m_callableWrapper = std::make_unique<Detail::CallableWrapper<CallableType, Out, In...>>(WTFMove(callable));
    6688        return *this;
    6789    }
     
    7092    Function& operator=(FunctionType f)
    7193    {
    72         m_callableWrapper = std::make_unique<CallableWrapper<FunctionType>>(WTFMove(f));
     94        m_callableWrapper = std::make_unique<Detail::CallableWrapper<FunctionType, Out, In...>>(WTFMove(f));
    7395        return *this;
    7496    }
     
    81103
    82104private:
    83     class CallableWrapperBase {
    84         WTF_MAKE_FAST_ALLOCATED;
    85     public:
    86         virtual ~CallableWrapperBase() { }
    87 
    88         virtual Out call(In...) = 0;
    89     };
    90 
    91     template<typename CallableType>
    92     class CallableWrapper : public CallableWrapperBase {
    93     public:
    94         explicit CallableWrapper(CallableType&& callable)
    95             : m_callable(WTFMove(callable))
    96         {
    97         }
    98 
    99         CallableWrapper(const CallableWrapper&) = delete;
    100         CallableWrapper& operator=(const CallableWrapper&) = delete;
    101 
    102         Out call(In... in) final { return m_callable(std::forward<In>(in)...); }
    103 
    104     private:
    105         CallableType m_callable;
    106     };
    107 
    108     std::unique_ptr<CallableWrapperBase> m_callableWrapper;
     105    std::unique_ptr<Detail::CallableWrapperBase<Out, In...>> m_callableWrapper;
    109106};
    110107
Note: See TracChangeset for help on using the changeset viewer.