diff options
Diffstat (limited to 'ipc/hal/DaemonRunnables.h')
-rw-r--r-- | ipc/hal/DaemonRunnables.h | 950 |
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 |