diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/GenericCallback.h')
-rw-r--r-- | Source/WebKit2/UIProcess/GenericCallback.h | 242 |
1 files changed, 103 insertions, 139 deletions
diff --git a/Source/WebKit2/UIProcess/GenericCallback.h b/Source/WebKit2/UIProcess/GenericCallback.h index 907e61589..1b67e9384 100644 --- a/Source/WebKit2/UIProcess/GenericCallback.h +++ b/Source/WebKit2/UIProcess/GenericCallback.h @@ -27,231 +27,195 @@ #define GenericCallback_h #include "APIError.h" +#include "APISerializedScriptValue.h" +#include "ProcessThrottler.h" #include "ShareableBitmap.h" #include "WKAPICast.h" +#include <functional> #include <wtf/HashMap.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> +#include <wtf/RunLoop.h> namespace WebKit { class CallbackBase : public RefCounted<CallbackBase> { public: + enum class Error { + None, + Unknown, + ProcessExited, + OwnerWasInvalidated, + }; + virtual ~CallbackBase() { } uint64_t callbackID() const { return m_callbackID; } + template<class T> + T* as() + { + if (T::type() == m_type) + return static_cast<T*>(this); + + return nullptr; + } + + virtual void invalidate(Error) = 0; + protected: - explicit CallbackBase(void* context) - : m_context(context) + struct TypeTag { }; + typedef const TypeTag* Type; + + explicit CallbackBase(Type type, const ProcessThrottler::BackgroundActivityToken& activityToken) + : m_type(type) , m_callbackID(generateCallbackID()) + , m_activityToken(activityToken) { } - void* context() const { return m_context; } - private: static uint64_t generateCallbackID() { + ASSERT(RunLoop::isMain()); static uint64_t uniqueCallbackID = 1; return uniqueCallbackID++; } - void* m_context; + Type m_type; uint64_t m_callbackID; + ProcessThrottler::BackgroundActivityToken m_activityToken; }; -class VoidCallback : public CallbackBase { +template<typename... T> +class GenericCallback : public CallbackBase { public: - typedef void (*CallbackFunction)(WKErrorRef, void*); + typedef std::function<void (T..., Error)> CallbackFunction; - static PassRefPtr<VoidCallback> create(void* context, CallbackFunction callback) + static PassRefPtr<GenericCallback> create(CallbackFunction callback, const ProcessThrottler::BackgroundActivityToken& activityToken = nullptr) { - return adoptRef(new VoidCallback(context, callback)); + return adoptRef(new GenericCallback(callback, activityToken)); } - virtual ~VoidCallback() + virtual ~GenericCallback() { ASSERT(!m_callback); } - void performCallback() + void performCallbackWithReturnValue(T... returnValue) { if (!m_callback) return; - m_callback(0, context()); + m_callback(returnValue..., Error::None); - m_callback = 0; - } - - void invalidate() - { - if (!m_callback) - return; - - RefPtr<API::Error> error = API::Error::create(); - m_callback(toAPI(error.get()), context()); - - m_callback = 0; - } - -private: - VoidCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) - { + m_callback = nullptr; } - CallbackFunction m_callback; -}; - -template<typename APIReturnValueType, typename InternalReturnValueType = typename APITypeInfo<APIReturnValueType>::ImplType> -class GenericCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(APIReturnValueType, WKErrorRef, void*); - - static PassRefPtr<GenericCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new GenericCallback(context, callback)); - } - - virtual ~GenericCallback() + void performCallback() { - ASSERT(!m_callback); + performCallbackWithReturnValue(); } - void performCallbackWithReturnValue(InternalReturnValueType returnValue) + void invalidate(Error error = Error::Unknown) final { - ASSERT(m_callback); - - m_callback(toAPI(returnValue), 0, context()); + if (!m_callback) + return; - m_callback = 0; - } - - void invalidate() - { - ASSERT(m_callback); + m_callback(typename std::remove_reference<T>::type()..., error); - RefPtr<API::Error> error = API::Error::create(); - m_callback(0, toAPI(error.get()), context()); - - m_callback = 0; + m_callback = nullptr; } private: - GenericCallback(void* context, CallbackFunction callback) - : CallbackBase(context) + GenericCallback(CallbackFunction callback, const ProcessThrottler::BackgroundActivityToken& activityToken) + : CallbackBase(type(), activityToken) , m_callback(callback) { } - CallbackFunction m_callback; -}; - -// FIXME: Make a version of CallbackBase with two arguments, and define ComputedPagesCallback as a specialization. -class ComputedPagesCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(const Vector<WebCore::IntRect>&, double, WKErrorRef, void*); - - static PassRefPtr<ComputedPagesCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new ComputedPagesCallback(context, callback)); - } - - virtual ~ComputedPagesCallback() + friend class CallbackBase; + static Type type() { - ASSERT(!m_callback); + static TypeTag tag; + return &tag; } - void performCallbackWithReturnValue(const Vector<WebCore::IntRect>& returnValue1, double returnValue2) - { - ASSERT(m_callback); + CallbackFunction m_callback; +}; - m_callback(returnValue1, returnValue2, 0, context()); +template<typename APIReturnValueType, typename InternalReturnValueType = typename APITypeInfo<APIReturnValueType>::ImplType*> +static typename GenericCallback<InternalReturnValueType>::CallbackFunction toGenericCallbackFunction(void* context, void (*callback)(APIReturnValueType, WKErrorRef, void*)) +{ + return [context, callback](InternalReturnValueType returnValue, CallbackBase::Error error) { + callback(toAPI(returnValue), error != CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context); + }; +} - m_callback = 0; - } - - void invalidate() - { - ASSERT(m_callback); +typedef GenericCallback<> VoidCallback; +typedef GenericCallback<const Vector<WebCore::IntRect>&, double> ComputedPagesCallback; +typedef GenericCallback<const ShareableBitmap::Handle&> ImageCallback; - RefPtr<API::Error> error = API::Error::create(); - m_callback(Vector<WebCore::IntRect>(), 0, toAPI(error.get()), context()); - - m_callback = 0; - } +template<typename T> +void invalidateCallbackMap(HashMap<uint64_t, T>& callbackMap, CallbackBase::Error error) +{ + Vector<T> callbacks; + copyValuesToVector(callbackMap, callbacks); + for (auto& callback : callbacks) + callback->invalidate(error); -private: + callbackMap.clear(); +} - ComputedPagesCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) +class CallbackMap { +public: + uint64_t put(PassRefPtr<CallbackBase> callback) { - } + ASSERT(!m_map.contains(callback->callbackID())); - CallbackFunction m_callback; -}; + uint64_t callbackID = callback->callbackID(); + m_map.set(callbackID, callback); + return callbackID; + } -class ImageCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(const ShareableBitmap::Handle&, WKErrorRef, void*); + template<unsigned I, typename T, typename... U> + struct GenericCallbackType { + typedef typename GenericCallbackType<I - 1, U..., T>::type type; + }; - static PassRefPtr<ImageCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new ImageCallback(context, callback)); - } + template<typename... U> + struct GenericCallbackType<1, CallbackBase::Error, U...> { + typedef GenericCallback<U...> type; + }; - virtual ~ImageCallback() + template<typename... T> + uint64_t put(std::function<void (T...)> function, const ProcessThrottler::BackgroundActivityToken& activityToken) { - ASSERT(!m_callback); + auto callback = GenericCallbackType<sizeof...(T), T...>::type::create(WTFMove(function), activityToken); + return put(callback); } - void performCallbackWithReturnValue(const ShareableBitmap::Handle& returnValue1) + template<class T> + RefPtr<T> take(uint64_t callbackID) { - ASSERT(m_callback); + auto base = m_map.take(callbackID); + if (!base) + return nullptr; - m_callback(returnValue1, 0, context()); - - m_callback = 0; + return adoptRef(base.leakRef()->as<T>()); } - void invalidate() + void invalidate(CallbackBase::Error error) { - ASSERT(m_callback); - - RefPtr<API::Error> error = API::Error::create(); - ShareableBitmap::Handle handle; - m_callback(handle, toAPI(error.get()), context()); - - m_callback = 0; + invalidateCallbackMap(m_map, error); } private: - - ImageCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) - { - } - - CallbackFunction m_callback; + HashMap<uint64_t, RefPtr<CallbackBase>> m_map; }; -template<typename T> -void invalidateCallbackMap(HashMap<uint64_t, T>& map) -{ - Vector<T> callbacksVector; - copyValuesToVector(map, callbacksVector); - for (size_t i = 0, size = callbacksVector.size(); i < size; ++i) - callbacksVector[i]->invalidate(); - map.clear(); -} - } // namespace WebKit #endif // GenericCallback_h |