Bug 1091575: Added general-purpose notification runnables for Bluetooth (under bluetooth2/), r=btian
authorThomas Zimmermann <tdz@users.sourceforge.net>
Fri, 14 Nov 2014 10:04:33 +0100
changeset 215744 b7d22b4ba3cf8208ef0c9f2c3f99bed65ca6e029
parent 215743 884b3d5eee633a3607b4d0c731bef326de5233c9
child 215745 c91863c880df6a7032131012475e30269ab5d5e0
push id27825
push userryanvm@gmail.com
push dateFri, 14 Nov 2014 22:14:56 +0000
treeherdermozilla-central@99892bdd512d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbtian
bugs1091575
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1091575: Added general-purpose notification runnables for Bluetooth (under bluetooth2/), r=btian A backend notification runnable in Bluetooth is used to transfer a notification from the I/O thread to the main thread; an interface runnable transfers and executes a result handler. Both are currently implemented by Bluetooth backends. This patch adds new runnables that are independend from any backend code or data structures.
dom/bluetooth2/BluetoothInterfaceHelpers.h
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth2/BluetoothInterfaceHelpers.h
@@ -0,0 +1,759 @@
+/* -*- 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_dom_bluetooth_bluetoothinterfacehelpers_h
+#define mozilla_dom_bluetooth_bluetoothinterfacehelpers_h
+
+#include "BluetoothCommon.h"
+#include "nsThreadUtils.h"
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+//
+// Result handling
+//
+// The classes of type |BluetoothResultRunnable[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 |BluetoothResultRunnable[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 BluetoothResultRunnable0 : public nsRunnable
+{
+public:
+  typedef BluetoothResultRunnable0<Obj, Res> SelfType;
+
+  template <typename InitOp>
+  static already_AddRefed<SelfType>
+  Create(Obj* aObj, Res (Obj::*aMethod)(), const InitOp& aInitOp)
+  {
+    nsRefPtr<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)
+  {
+    nsRefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp);
+    if (!runnable) {
+      BT_LOGR("BluetoothResultRunnable0::Create failed");
+      return;
+    }
+    nsresult rv = NS_DispatchToMainThread(runnable);
+    if (NS_FAILED(rv)) {
+      BT_LOGR("NS_DispatchToMainThread failed: %X", rv);
+    }
+  }
+
+  NS_METHOD
+  Run() MOZ_OVERRIDE
+  {
+    ((*mObj).*mMethod)();
+    return NS_OK;
+  }
+
+private:
+  BluetoothResultRunnable0(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();
+  }
+
+  nsRefPtr<Obj> mObj;
+  void (Obj::*mMethod)();
+};
+
+template <typename Obj, typename Res, typename Tin1, typename Arg1>
+class BluetoothResultRunnable1 : public nsRunnable
+{
+public:
+  typedef BluetoothResultRunnable1<Obj, Res, Tin1, Arg1> SelfType;
+
+  template <typename InitOp>
+  static already_AddRefed<SelfType>
+  Create(Obj* aObj, Res (Obj::*aMethod)(Arg1), const InitOp& aInitOp)
+  {
+    nsRefPtr<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)
+  {
+    nsRefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp);
+    if (!runnable) {
+      BT_LOGR("BluetoothResultRunnable1::Create failed");
+      return;
+    }
+    nsresult rv = NS_DispatchToMainThread(runnable);
+    if (NS_FAILED(rv)) {
+      BT_LOGR("NS_DispatchToMainThread failed: %X", rv);
+    }
+  }
+
+  NS_METHOD
+  Run() MOZ_OVERRIDE
+  {
+    ((*mObj).*mMethod)(mArg1);
+    return NS_OK;
+  }
+
+private:
+  BluetoothResultRunnable1(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);
+  }
+
+  nsRefPtr<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 BluetoothResultRunnable3 : public nsRunnable
+{
+public:
+  typedef BluetoothResultRunnable3<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)
+  {
+    nsRefPtr<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)
+  {
+    nsRefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp);
+    if (!runnable) {
+      BT_LOGR("BluetoothResultRunnable3::Create failed");
+      return;
+    }
+    nsresult rv = NS_DispatchToMainThread(runnable);
+    if (NS_FAILED(rv)) {
+      BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
+    }
+  }
+
+  NS_METHOD
+  Run() MOZ_OVERRIDE
+  {
+    ((*mObj).*mMethod)(mArg1, mArg2, mArg3);
+    return NS_OK;
+  }
+
+private:
+  BluetoothResultRunnable3(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);
+  }
+
+  nsRefPtr<Obj> mObj;
+  Res (Obj::*mMethod)(Arg1, Arg2, Arg3);
+  Tin1 mArg1;
+  Tin2 mArg2;
+  Tin3 mArg3;
+};
+
+//
+// Notification handling
+//
+// The classes of type |BluetoothNotificationRunnable[0..5]| 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 |BluetoothNotificationRunnable[1..5]| 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 BluetoothNotificationRunnable0 : public nsRunnable
+{
+public:
+  typedef typename ObjectWrapper::ObjectType  ObjectType;
+  typedef BluetoothNotificationRunnable0<ObjectWrapper, Res> SelfType;
+
+  template<typename InitOp>
+  static already_AddRefed<SelfType>
+  Create(Res (ObjectType::*aMethod)(), const InitOp& aInitOp)
+  {
+    nsRefPtr<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)
+  {
+    nsRefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+    if (!runnable) {
+      BT_WARNING("BluetoothNotificationRunnable0::Create failed");
+      return;
+    }
+    nsresult rv = NS_DispatchToMainThread(runnable);
+    if (NS_FAILED(rv)) {
+      BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
+    }
+  }
+
+  NS_METHOD
+  Run() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    ObjectType* obj = ObjectWrapper::GetInstance();
+    if (!obj) {
+      BT_WARNING("Notification handler not initialized");
+    } else {
+      ((*obj).*mMethod)();
+    }
+    return NS_OK;
+  }
+
+private:
+  BluetoothNotificationRunnable0(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 BluetoothNotificationRunnable1 : public nsRunnable
+{
+public:
+  typedef typename ObjectWrapper::ObjectType  ObjectType;
+  typedef BluetoothNotificationRunnable1<ObjectWrapper, Res,
+                                         Tin1, Arg1> SelfType;
+
+  template <typename InitOp>
+  static already_AddRefed<SelfType>
+  Create(Res (ObjectType::*aMethod)(Arg1), const InitOp& aInitOp)
+  {
+    nsRefPtr<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)
+  {
+    nsRefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+
+    if (!runnable) {
+      BT_WARNING("BluetoothNotificationRunnable1::Create failed");
+      return;
+    }
+    nsresult rv = NS_DispatchToMainThread(runnable);
+    if (NS_FAILED(rv)) {
+      BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
+    }
+  }
+
+  NS_METHOD
+  Run() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    ObjectType* obj = ObjectWrapper::GetInstance();
+    if (!obj) {
+      BT_WARNING("Notification handler not initialized");
+    } else {
+      ((*obj).*mMethod)(mArg1);
+    }
+    return NS_OK;
+  }
+
+private:
+  BluetoothNotificationRunnable1(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 BluetoothNotificationRunnable2 : public nsRunnable
+{
+public:
+  typedef typename ObjectWrapper::ObjectType  ObjectType;
+  typedef BluetoothNotificationRunnable2<ObjectWrapper, Res,
+                                         Tin1, Tin2,
+                                         Arg1, Arg2> SelfType;
+
+  template <typename InitOp>
+  static already_AddRefed<SelfType>
+  Create(Res (ObjectType::*aMethod)(Arg1, Arg2), const InitOp& aInitOp)
+  {
+    nsRefPtr<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)
+  {
+    nsRefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+    if (!runnable) {
+      BT_WARNING("BluetoothNotificationRunnable2::Create failed");
+      return;
+    }
+    nsresult rv = NS_DispatchToMainThread(runnable);
+    if (NS_FAILED(rv)) {
+      BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
+    }
+  }
+
+  NS_METHOD
+  Run() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    ObjectType* obj = ObjectWrapper::GetInstance();
+    if (!obj) {
+      BT_WARNING("Notification handler not initialized");
+    } else {
+      ((*obj).*mMethod)(mArg1, mArg2);
+    }
+    return NS_OK;
+  }
+
+private:
+  BluetoothNotificationRunnable2(
+    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 BluetoothNotificationRunnable3 : public nsRunnable
+{
+public:
+  typedef typename ObjectWrapper::ObjectType  ObjectType;
+  typedef BluetoothNotificationRunnable3<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)
+  {
+    nsRefPtr<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)
+  {
+    nsRefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+    if (!runnable) {
+      BT_WARNING("BluetoothNotificationRunnable3::Create failed");
+      return;
+    }
+    nsresult rv = NS_DispatchToMainThread(runnable);
+    if (NS_FAILED(rv)) {
+      BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
+    }
+  }
+
+  NS_METHOD
+  Run() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    ObjectType* obj = ObjectWrapper::GetInstance();
+    if (!obj) {
+      BT_WARNING("Notification handler not initialized");
+    } else {
+      ((*obj).*mMethod)(mArg1, mArg2, mArg3);
+    }
+    return NS_OK;
+  }
+
+private:
+  BluetoothNotificationRunnable3(
+    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 BluetoothNotificationRunnable4 : public nsRunnable
+{
+public:
+  typedef typename ObjectWrapper::ObjectType  ObjectType;
+  typedef BluetoothNotificationRunnable4<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)
+  {
+    nsRefPtr<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)
+  {
+    nsRefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+    if (!runnable) {
+      BT_WARNING("BluetoothNotificationRunnable4::Create failed");
+      return;
+    }
+    nsresult rv = NS_DispatchToMainThread(runnable);
+    if (NS_FAILED(rv)) {
+      BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
+    }
+  }
+
+  NS_METHOD
+  Run() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    ObjectType* obj = ObjectWrapper::GetInstance();
+    if (!obj) {
+      BT_WARNING("Notification handler not initialized");
+    } else {
+      ((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4);
+    }
+    return NS_OK;
+  }
+
+private:
+  BluetoothNotificationRunnable4(
+    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 BluetoothNotificationRunnable5 : public nsRunnable
+{
+public:
+  typedef typename ObjectWrapper::ObjectType  ObjectType;
+  typedef BluetoothNotificationRunnable5<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)
+  {
+    nsRefPtr<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)
+  {
+    nsRefPtr<SelfType> runnable = Create(aMethod, aInitOp);
+    if (!runnable) {
+      BT_WARNING("BluetoothNotificationRunnable5::Create failed");
+      return;
+    }
+    nsresult rv = NS_DispatchToMainThread(runnable);
+    if (NS_FAILED(rv)) {
+      BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
+    }
+  }
+
+  NS_METHOD
+  Run() MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    ObjectType* obj = ObjectWrapper::GetInstance();
+    if (!obj) {
+      BT_WARNING("Notification handler not initialized");
+    } else {
+      ((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4, mArg5);
+    }
+    return NS_OK;
+  }
+
+private:
+  BluetoothNotificationRunnable5(
+    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;
+};
+
+//
+// Init operators
+//
+// Below are general-purpose init operators for Bluetooth. The classes
+// of type |ConstantInitOp[1..3]| initialize results or notifications
+// with constant values.
+//
+
+template <typename T1>
+class ConstantInitOp1 MOZ_FINAL
+{
+public:
+  ConstantInitOp1(const T1& aArg1)
+  : mArg1(aArg1)
+  { }
+
+  nsresult operator () (T1& aArg1) const
+  {
+    aArg1 = mArg1;
+
+    return NS_OK;
+  }
+
+private:
+  const T1& mArg1;
+};
+
+template <typename T1, typename T2>
+class ConstantInitOp2 MOZ_FINAL
+{
+public:
+  ConstantInitOp2(const T1& aArg1, const T2& aArg2)
+  : mArg1(aArg1)
+  , mArg2(aArg2)
+  { }
+
+  nsresult operator () (T1& aArg1, T2& aArg2) const
+  {
+    aArg1 = mArg1;
+    aArg2 = mArg2;
+
+    return NS_OK;
+  }
+
+private:
+  const T1& mArg1;
+  const T2& mArg2;
+};
+
+template <typename T1, typename T2, typename T3>
+class ConstantInitOp3 MOZ_FINAL
+{
+public:
+  ConstantInitOp3(const T1& aArg1, const T2& aArg2, const T3& aArg3)
+  : mArg1(aArg1)
+  , mArg2(aArg2)
+  , mArg3(aArg3)
+  { }
+
+  nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3) const
+  {
+    aArg1 = mArg1;
+    aArg2 = mArg2;
+    aArg3 = mArg3;
+
+    return NS_OK;
+  }
+
+private:
+  const T1& mArg1;
+  const T2& mArg2;
+  const T3& mArg3;
+};
+
+END_BLUETOOTH_NAMESPACE
+
+#endif