summaryrefslogtreecommitdiffstats
path: root/ipc/hal/DaemonRunnables.h
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/hal/DaemonRunnables.h')
-rw-r--r--ipc/hal/DaemonRunnables.h950
1 files changed, 950 insertions, 0 deletions
diff --git a/ipc/hal/DaemonRunnables.h b/ipc/hal/DaemonRunnables.h
new file mode 100644
index 000000000..e4a528a9b
--- /dev/null
+++ b/ipc/hal/DaemonRunnables.h
@@ -0,0 +1,950 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_ipc_DaemonRunnables_h
+#define mozilla_ipc_DaemonRunnables_h
+
+#include "mozilla/Unused.h"
+#include "mozilla/UniquePtr.h"
+#include "nsThreadUtils.h"
+
+namespace mozilla {
+namespace ipc {
+
+namespace details {
+
+class DaemonRunnable : public Runnable
+{
+protected:
+ DaemonRunnable() = default;
+ virtual ~DaemonRunnable() = default;
+
+ template<typename Out, typename In>
+ static Out& ConvertArg(In& aArg)
+ {
+ return aArg;
+ }
+
+ template<typename Out, typename In>
+ static Out ConvertArg(UniquePtr<In>& aArg)
+ {
+ return aArg.get();
+ }
+};
+
+} // namespace detail
+
+//
+// Result handling
+//
+// The classes of type |DaemonResultRunnable[0..3]| transfer a result
+// handler from the I/O thread to the main thread for execution. Call
+// the methods |Create| and |Dispatch| to create or create-and-dispatch
+// a result runnable.
+//
+// You need to specify the called method. The |Create| and |Dispatch|
+// methods of |DaemonResultRunnable[1..3]| receive an extra argument
+// for initializing the result's arguments. During creation, the result
+// runnable calls the supplied class's call operator with the result's
+// argument. This is where initialization and conversion from backend-
+// specific types is performed.
+//
+
+template <typename Obj, typename Res>
+class DaemonResultRunnable0 final : public details::DaemonRunnable
+{
+public:
+ typedef DaemonResultRunnable0<Obj, Res> SelfType;
+
+ template <typename InitOp>
+ static already_AddRefed<SelfType>
+ Create(Obj* aObj, Res (Obj::*aMethod)(), const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aObj, aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template <typename InitOp>
+ static void
+ Dispatch(Obj* aObj, Res (Obj::*aMethod)(), const InitOp& aInitOp)
+ {
+ if (!aObj) {
+ return; // silently return if no result runnable has been given
+ }
+ RefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ ((*mObj).*mMethod)();
+ return NS_OK;
+ }
+
+private:
+ DaemonResultRunnable0(Obj* aObj, Res (Obj::*aMethod)())
+ : mObj(aObj)
+ , mMethod(aMethod)
+ {
+ MOZ_ASSERT(mObj);
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ return aInitOp();
+ }
+
+ RefPtr<Obj> mObj;
+ void (Obj::*mMethod)();
+};
+
+template <typename Obj, typename Res, typename Tin1, typename Arg1>
+class DaemonResultRunnable1 final : public details::DaemonRunnable
+{
+public:
+ typedef DaemonResultRunnable1<Obj, Res, Tin1, Arg1> SelfType;
+
+ template <typename InitOp>
+ static already_AddRefed<SelfType>
+ Create(Obj* aObj, Res (Obj::*aMethod)(Arg1), const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aObj, aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template <typename InitOp>
+ static void
+ Dispatch(Obj* aObj, Res (Obj::*aMethod)(Arg1), const InitOp& aInitOp)
+ {
+ if (!aObj) {
+ return; // silently return if no result runnable has been given
+ }
+ RefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ ((*mObj).*mMethod)(ConvertArg<Arg1>(mArg1));
+ return NS_OK;
+ }
+
+private:
+ DaemonResultRunnable1(Obj* aObj, Res (Obj::*aMethod)(Arg1))
+ : mObj(aObj)
+ , mMethod(aMethod)
+ {
+ MOZ_ASSERT(mObj);
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ return aInitOp(mArg1);
+ }
+
+ RefPtr<Obj> mObj;
+ Res (Obj::*mMethod)(Arg1);
+ Tin1 mArg1;
+};
+
+template <typename Obj, typename Res,
+ typename Tin1, typename Tin2, typename Tin3,
+ typename Arg1, typename Arg2, typename Arg3>
+class DaemonResultRunnable3 final : public details::DaemonRunnable
+{
+public:
+ typedef DaemonResultRunnable3<Obj, Res,
+ Tin1, Tin2, Tin3,
+ Arg1, Arg2, Arg3> SelfType;
+
+ template<typename InitOp>
+ static already_AddRefed<SelfType>
+ Create(Obj* aObj, Res (Obj::*aMethod)(Arg1, Arg2, Arg3),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aObj, aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template<typename InitOp>
+ static void
+ Dispatch(Obj* aObj, Res (Obj::*aMethod)(Arg1, Arg2, Arg3),
+ const InitOp& aInitOp)
+ {
+ if (!aObj) {
+ return; // silently return if no result runnable has been given
+ }
+ RefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ ((*mObj).*mMethod)(ConvertArg<Arg1>(mArg1),
+ ConvertArg<Arg2>(mArg2),
+ ConvertArg<Arg3>(mArg3));
+ return NS_OK;
+ }
+
+private:
+ DaemonResultRunnable3(Obj* aObj, Res (Obj::*aMethod)(Arg1, Arg2, Arg3))
+ : mObj(aObj)
+ , mMethod(aMethod)
+ {
+ MOZ_ASSERT(mObj);
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult
+ Init(const InitOp& aInitOp)
+ {
+ return aInitOp(mArg1, mArg2, mArg3);
+ }
+
+ RefPtr<Obj> mObj;
+ Res (Obj::*mMethod)(Arg1, Arg2, Arg3);
+ Tin1 mArg1;
+ Tin2 mArg2;
+ Tin3 mArg3;
+};
+
+//
+// Notification handling
+//
+// The classes of type |DaemonNotificationRunnable[0..9]| transfer a
+// notification from the I/O thread to a notification handler on the
+// main thread. Call the methods |Create| and |Dispatch| to create or
+// create-and-dispatch a notification runnable.
+//
+// Like with result runnables, you need to specify the called method.
+// And like with result runnables, the |Create| and |Dispatch| methods
+// of |DaemonNotificationRunnable[1..9]| receive an extra argument
+// for initializing the notification's arguments. During creation, the
+// notification runnable calls the class's call operator with the
+// notification's argument. This is where initialization and conversion
+// from backend-specific types is performed.
+//
+
+template <typename ObjectWrapper, typename Res>
+class DaemonNotificationRunnable0 final : public details::DaemonRunnable
+{
+public:
+ typedef typename ObjectWrapper::ObjectType ObjectType;
+ typedef DaemonNotificationRunnable0<ObjectWrapper, Res> SelfType;
+
+ template<typename InitOp>
+ static already_AddRefed<SelfType>
+ Create(Res (ObjectType::*aMethod)(), const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template<typename InitOp>
+ static void
+ Dispatch(Res (ObjectType::*aMethod)(), const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ ObjectType* obj = ObjectWrapper::GetInstance();
+ if (!obj) {
+ NS_WARNING("Notification handler not initialized");
+ } else {
+ ((*obj).*mMethod)();
+ }
+ return NS_OK;
+ }
+
+private:
+ DaemonNotificationRunnable0(Res (ObjectType::*aMethod)())
+ : mMethod(aMethod)
+ {
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ return aInitOp();
+ }
+
+ Res (ObjectType::*mMethod)();
+};
+
+template <typename ObjectWrapper, typename Res,
+ typename Tin1, typename Arg1=Tin1>
+class DaemonNotificationRunnable1 final : public details::DaemonRunnable
+{
+public:
+ typedef typename ObjectWrapper::ObjectType ObjectType;
+ typedef DaemonNotificationRunnable1<ObjectWrapper, Res,
+ Tin1, Arg1> SelfType;
+
+ template <typename InitOp>
+ static already_AddRefed<SelfType>
+ Create(Res (ObjectType::*aMethod)(Arg1), const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template <typename InitOp>
+ static void
+ Dispatch(Res (ObjectType::*aMethod)(Arg1), const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ ObjectType* obj = ObjectWrapper::GetInstance();
+ if (!obj) {
+ NS_WARNING("Notification handler not initialized");
+ } else {
+ ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1));
+ }
+ return NS_OK;
+ }
+
+private:
+ DaemonNotificationRunnable1(Res (ObjectType::*aMethod)(Arg1))
+ : mMethod(aMethod)
+ {
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ nsresult rv = aInitOp(mArg1);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
+ Res (ObjectType::*mMethod)(Arg1);
+ Tin1 mArg1;
+};
+
+template <typename ObjectWrapper, typename Res,
+ typename Tin1, typename Tin2,
+ typename Arg1=Tin1, typename Arg2=Tin2>
+class DaemonNotificationRunnable2 final : public details::DaemonRunnable
+{
+public:
+ typedef typename ObjectWrapper::ObjectType ObjectType;
+ typedef DaemonNotificationRunnable2<ObjectWrapper, Res,
+ Tin1, Tin2,
+ Arg1, Arg2> SelfType;
+
+ template <typename InitOp>
+ static already_AddRefed<SelfType>
+ Create(Res (ObjectType::*aMethod)(Arg1, Arg2), const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template <typename InitOp>
+ static void
+ Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2), const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ ObjectType* obj = ObjectWrapper::GetInstance();
+ if (!obj) {
+ NS_WARNING("Notification handler not initialized");
+ } else {
+ ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1),
+ ConvertArg<Arg2>(mArg2));
+ }
+ return NS_OK;
+ }
+
+private:
+ DaemonNotificationRunnable2(
+ Res (ObjectType::*aMethod)(Arg1, Arg2))
+ : mMethod(aMethod)
+ {
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ nsresult rv = aInitOp(mArg1, mArg2);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
+ Res (ObjectType::*mMethod)(Arg1, Arg2);
+ Tin1 mArg1;
+ Tin2 mArg2;
+};
+
+template <typename ObjectWrapper, typename Res,
+ typename Tin1, typename Tin2, typename Tin3,
+ typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3>
+class DaemonNotificationRunnable3 final : public details::DaemonRunnable
+{
+public:
+ typedef typename ObjectWrapper::ObjectType ObjectType;
+ typedef DaemonNotificationRunnable3<ObjectWrapper, Res,
+ Tin1, Tin2, Tin3,
+ Arg1, Arg2, Arg3> SelfType;
+
+ template <typename InitOp>
+ static already_AddRefed<SelfType>
+ Create(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3), const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template <typename InitOp>
+ static void
+ Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ ObjectType* obj = ObjectWrapper::GetInstance();
+ if (!obj) {
+ NS_WARNING("Notification handler not initialized");
+ } else {
+ ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1),
+ ConvertArg<Arg2>(mArg2),
+ ConvertArg<Arg3>(mArg3));
+ }
+ return NS_OK;
+ }
+
+private:
+ DaemonNotificationRunnable3(
+ Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3))
+ : mMethod(aMethod)
+ {
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ nsresult rv = aInitOp(mArg1, mArg2, mArg3);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
+ Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3);
+ Tin1 mArg1;
+ Tin2 mArg2;
+ Tin3 mArg3;
+};
+
+template <typename ObjectWrapper, typename Res,
+ typename Tin1, typename Tin2, typename Tin3, typename Tin4,
+ typename Arg1=Tin1, typename Arg2=Tin2,
+ typename Arg3=Tin3, typename Arg4=Tin4>
+class DaemonNotificationRunnable4 final : public details::DaemonRunnable
+{
+public:
+ typedef typename ObjectWrapper::ObjectType ObjectType;
+ typedef DaemonNotificationRunnable4<ObjectWrapper, Res,
+ Tin1, Tin2, Tin3, Tin4, Arg1, Arg2, Arg3, Arg4> SelfType;
+
+ template <typename InitOp>
+ static already_AddRefed<SelfType> Create(
+ Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template <typename InitOp>
+ static void
+ Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ ObjectType* obj = ObjectWrapper::GetInstance();
+ if (!obj) {
+ NS_WARNING("Notification handler not initialized");
+ } else {
+ ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1),
+ ConvertArg<Arg2>(mArg2),
+ ConvertArg<Arg3>(mArg3),
+ ConvertArg<Arg4>(mArg4));
+ }
+ return NS_OK;
+ }
+
+private:
+ DaemonNotificationRunnable4(
+ Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4))
+ : mMethod(aMethod)
+ {
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
+ Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4);
+ Tin1 mArg1;
+ Tin2 mArg2;
+ Tin3 mArg3;
+ Tin4 mArg4;
+};
+
+template <typename ObjectWrapper, typename Res,
+ typename Tin1, typename Tin2, typename Tin3,
+ typename Tin4, typename Tin5,
+ typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3,
+ typename Arg4=Tin4, typename Arg5=Tin5>
+class DaemonNotificationRunnable5 final : public details::DaemonRunnable
+{
+public:
+ typedef typename ObjectWrapper::ObjectType ObjectType;
+ typedef DaemonNotificationRunnable5<ObjectWrapper, Res,
+ Tin1, Tin2, Tin3, Tin4, Tin5, Arg1, Arg2, Arg3, Arg4, Arg5> SelfType;
+
+ template <typename InitOp>
+ static already_AddRefed<SelfType> Create(
+ Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template <typename InitOp>
+ static void
+ Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ ObjectType* obj = ObjectWrapper::GetInstance();
+ if (!obj) {
+ NS_WARNING("Notification handler not initialized");
+ } else {
+ ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1),
+ ConvertArg<Arg2>(mArg2),
+ ConvertArg<Arg3>(mArg3),
+ ConvertArg<Arg4>(mArg4),
+ ConvertArg<Arg5>(mArg5));
+ }
+ return NS_OK;
+ }
+
+private:
+ DaemonNotificationRunnable5(
+ Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5))
+ : mMethod(aMethod)
+ {
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, mArg5);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
+ Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5);
+ Tin1 mArg1;
+ Tin2 mArg2;
+ Tin3 mArg3;
+ Tin4 mArg4;
+ Tin5 mArg5;
+};
+
+template <typename ObjectWrapper, typename Res,
+ typename Tin1, typename Tin2, typename Tin3,
+ typename Tin4, typename Tin5, typename Tin6,
+ typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3,
+ typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6>
+class DaemonNotificationRunnable6 final : public details::DaemonRunnable
+{
+public:
+ typedef typename ObjectWrapper::ObjectType ObjectType;
+ typedef DaemonNotificationRunnable6<ObjectWrapper, Res,
+ Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6>
+ SelfType;
+
+ template <typename InitOp>
+ static already_AddRefed<SelfType> Create(
+ Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template <typename InitOp>
+ static void
+ Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ ObjectType* obj = ObjectWrapper::GetInstance();
+ if (!obj) {
+ NS_WARNING("Notification handler not initialized");
+ } else {
+ ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1),
+ ConvertArg<Arg2>(mArg2),
+ ConvertArg<Arg3>(mArg3),
+ ConvertArg<Arg4>(mArg4),
+ ConvertArg<Arg5>(mArg5),
+ ConvertArg<Arg6>(mArg6));
+ }
+ return NS_OK;
+ }
+
+private:
+ DaemonNotificationRunnable6(
+ Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6))
+ : mMethod(aMethod)
+ {
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, mArg5, mArg6);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
+ Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
+ Tin1 mArg1;
+ Tin2 mArg2;
+ Tin3 mArg3;
+ Tin4 mArg4;
+ Tin5 mArg5;
+ Tin6 mArg6;
+};
+
+template <typename ObjectWrapper, typename Res,
+ typename Tin1, typename Tin2, typename Tin3,
+ typename Tin4, typename Tin5, typename Tin6,
+ typename Tin7, typename Tin8,
+ typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3,
+ typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6,
+ typename Arg7=Tin7, typename Arg8=Tin8>
+class DaemonNotificationRunnable8 final : public details::DaemonRunnable
+{
+public:
+ typedef typename ObjectWrapper::ObjectType ObjectType;
+ typedef DaemonNotificationRunnable8<ObjectWrapper, Res,
+ Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Tin7, Tin8,
+ Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8> SelfType;
+
+ template <typename InitOp>
+ static already_AddRefed<SelfType> Create(
+ Res (ObjectType::*aMethod)(
+ Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template <typename InitOp>
+ static void
+ Dispatch(
+ Res (ObjectType::*aMethod)(
+ Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ ObjectType* obj = ObjectWrapper::GetInstance();
+ if (!obj) {
+ NS_WARNING("Notification handler not initialized");
+ } else {
+ ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1),
+ ConvertArg<Arg2>(mArg2),
+ ConvertArg<Arg3>(mArg3),
+ ConvertArg<Arg4>(mArg4),
+ ConvertArg<Arg5>(mArg5),
+ ConvertArg<Arg6>(mArg6),
+ ConvertArg<Arg7>(mArg7),
+ ConvertArg<Arg8>(mArg8));
+ }
+ return NS_OK;
+ }
+
+private:
+ DaemonNotificationRunnable8(
+ Res (ObjectType::*aMethod)(
+ Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8))
+ : mMethod(aMethod)
+ {
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4,
+ mArg5, mArg6, mArg7, mArg8);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
+ Res (ObjectType::*mMethod)(
+ Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
+ Tin1 mArg1;
+ Tin2 mArg2;
+ Tin3 mArg3;
+ Tin4 mArg4;
+ Tin5 mArg5;
+ Tin6 mArg6;
+ Tin7 mArg7;
+ Tin8 mArg8;
+};
+
+template <typename ObjectWrapper, typename Res,
+ typename Tin1, typename Tin2, typename Tin3,
+ typename Tin4, typename Tin5, typename Tin6,
+ typename Tin7, typename Tin8, typename Tin9,
+ typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3,
+ typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6,
+ typename Arg7=Tin7, typename Arg8=Tin8, typename Arg9=Tin9>
+class DaemonNotificationRunnable9 final : public details::DaemonRunnable
+{
+public:
+ typedef typename ObjectWrapper::ObjectType ObjectType;
+ typedef DaemonNotificationRunnable9<ObjectWrapper, Res,
+ Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Tin7, Tin8, Tin9,
+ Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9> SelfType;
+
+ template <typename InitOp>
+ static already_AddRefed<SelfType> Create(
+ Res (ObjectType::*aMethod)(
+ Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable(new SelfType(aMethod));
+ if (NS_FAILED(runnable->Init(aInitOp))) {
+ return nullptr;
+ }
+ return runnable.forget();
+ }
+
+ template <typename InitOp>
+ static void
+ Dispatch(
+ Res (ObjectType::*aMethod)(
+ Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9),
+ const InitOp& aInitOp)
+ {
+ RefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+ if (!runnable) {
+ return;
+ }
+ Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
+ }
+
+ NS_IMETHOD Run() override
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ ObjectType* obj = ObjectWrapper::GetInstance();
+ if (!obj) {
+ NS_WARNING("Notification handler not initialized");
+ } else {
+ ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1),
+ ConvertArg<Arg2>(mArg2),
+ ConvertArg<Arg3>(mArg3),
+ ConvertArg<Arg4>(mArg4),
+ ConvertArg<Arg5>(mArg5),
+ ConvertArg<Arg6>(mArg6),
+ ConvertArg<Arg7>(mArg7),
+ ConvertArg<Arg8>(mArg8),
+ ConvertArg<Arg9>(mArg9));
+ }
+ return NS_OK;
+ }
+
+private:
+ DaemonNotificationRunnable9(
+ Res (ObjectType::*aMethod)(
+ Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9))
+ : mMethod(aMethod)
+ {
+ MOZ_ASSERT(mMethod);
+ }
+
+ template<typename InitOp>
+ nsresult Init(const InitOp& aInitOp)
+ {
+ nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4,
+ mArg5, mArg6, mArg7, mArg8, mArg9);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
+ Res (ObjectType::*mMethod)(
+ Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9);
+ Tin1 mArg1;
+ Tin2 mArg2;
+ Tin3 mArg3;
+ Tin4 mArg4;
+ Tin5 mArg5;
+ Tin6 mArg6;
+ Tin7 mArg7;
+ Tin8 mArg8;
+ Tin9 mArg9;
+};
+
+}
+}
+
+#endif // mozilla_ipc_DaemonRunnables_h