summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/GenericCallback.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/GenericCallback.h')
-rw-r--r--Source/WebKit2/UIProcess/GenericCallback.h242
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