Bug 968803 - part 2 - statically type runnable classes that return a result; r=ekr
authorNathan Froyd <froydnj@mozilla.com>
Thu, 06 Feb 2014 10:21:55 -0500
changeset 181428 8a6c3ab28bbc433485d29e13fb905682495d785c
parent 181427 b30e471400c5d320fd1d78c75870f6f0586bff0e
child 181429 6c9e1af09baea27a279dd648385ea9ac3d81cd86
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersekr
bugs968803
milestone32.0a1
Bug 968803 - part 2 - statically type runnable classes that return a result; r=ekr
media/mtransport/runnable_utils.h
media/mtransport/runnable_utils.py
media/mtransport/runnable_utils_generated.h
media/mtransport/test/ice_unittest.cpp
media/mtransport/test/transport_unittests.cpp
--- a/media/mtransport/runnable_utils.h
+++ b/media/mtransport/runnable_utils.h
@@ -10,22 +10,53 @@
 #define runnable_utils_h__
 
 #include "nsThreadUtils.h"
 #include "mozilla/RefPtr.h"
 
 // Abstract base class for all of our templates
 namespace mozilla {
 
+namespace detail {
+
+enum RunnableResult {
+  NoResult,
+  ReturnsResult
+};
+
+static inline nsresult
+RunOnThreadInternal(nsIEventTarget *thread, nsIRunnable *runnable, uint32_t flags)
+{
+  nsCOMPtr<nsIRunnable> runnable_ref(runnable);
+  if (thread) {
+    bool on;
+    nsresult rv;
+    rv = thread->IsOnCurrentThread(&on);
+
+    // If the target thread has already shut down, we don't want to assert.
+    if (rv != NS_ERROR_NOT_INITIALIZED) {
+      MOZ_ASSERT(NS_SUCCEEDED(rv));
+    }
+
+    NS_ENSURE_SUCCESS(rv, rv);
+    if (!on) {
+      return thread->Dispatch(runnable_ref, flags);
+    }
+  }
+  return runnable_ref->Run();
+}
+
+template<RunnableResult result>
 class runnable_args_base : public nsRunnable {
  public:
   NS_IMETHOD Run() = 0;
-  virtual bool returns_value() const { return false; }
 };
 
+}
+
 // The generated file contains four major function templates
 // (in variants for arbitrary numbers of arguments up to 10,
 // which is why it is machine generated). The four templates
 // are:
 //
 // WrapRunnable(o, m, ...) -- wraps a member function m of an object ptr o
 // WrapRunnableRet(o, m, ..., r) -- wraps a member function m of an object ptr o
 //                                  the function returns something that can
@@ -33,44 +64,24 @@ class runnable_args_base : public nsRunn
 // WrapRunnableNM(f, ...) -- wraps a function f
 // WrapRunnableNMRet(f, ..., r) -- wraps a function f that returns something
 //                                 that can be assigned to *r
 //
 // All of these template functions return a Runnable* which can be passed
 // to Dispatch().
 #include "runnable_utils_generated.h"
 
-// Temporary hack. Really we want to have a template which will do this
-static inline nsresult RUN_ON_THREAD(nsIEventTarget *thread, nsIRunnable *runnable, uint32_t flags) {
-  RefPtr<nsIRunnable> runnable_ref(runnable);
-  if (thread) {
-    bool on;
-    nsresult rv;
-    rv = thread->IsOnCurrentThread(&on);
-
-    // If the target thread has already shut down, we don't want to assert.
-    if (rv != NS_ERROR_NOT_INITIALIZED) {
-      MOZ_ASSERT(NS_SUCCEEDED(rv));
-    }
-
-    NS_ENSURE_SUCCESS(rv, rv);
-    if(!on) {
-      return thread->Dispatch(runnable_ref, flags);
-    }
-  }
-  return runnable_ref->Run();
+static inline nsresult RUN_ON_THREAD(nsIEventTarget *thread, detail::runnable_args_base<detail::NoResult> *runnable, uint32_t flags) {
+  return detail::RunOnThreadInternal(thread, static_cast<nsIRunnable *>(runnable), flags);
 }
 
-static inline nsresult RUN_ON_THREAD(nsIEventTarget *thread, runnable_args_base *runnable, uint32_t flags) {
-  // Detect attempts to return a value when in async mode, since this
-  // most likely means someone is trying to assign to a heap variable
-  // which is now out of scope.
-  MOZ_ASSERT((!(runnable->returns_value()) || (flags != NS_DISPATCH_NORMAL)));
-
-  return RUN_ON_THREAD(thread, static_cast<nsIRunnable *>(runnable), flags);
+static inline nsresult
+RUN_ON_THREAD(nsIEventTarget *thread, detail::runnable_args_base<detail::ReturnsResult> *runnable)
+{
+  return detail::RunOnThreadInternal(thread, static_cast<nsIRunnable *>(runnable), NS_DISPATCH_SYNC);
 }
 
 #ifdef DEBUG
 #define ASSERT_ON_THREAD(t) do {                \
     if (t) {                                    \
       bool on;                                    \
       nsresult rv;                                \
       rv = t->IsOnCurrentThread(&on);             \
--- a/media/mtransport/runnable_utils.py
+++ b/media/mtransport/runnable_utils.py
@@ -72,40 +72,42 @@ def gen_types(args, member):
 def runnable_class_name(args, ret=False, member=True):
     if member:
         nm = "m"
     else:
         nm = "nm"
 
     if ret:
         class_suffix = "_ret"
+        enum_specializer = "detail::ReturnsResult"
     else:
         class_suffix = ""
+        enum_specializer = "detail::NoResult"
 
-    return "runnable_args_%s_%d%s" % (nm, args, class_suffix)
+    return "runnable_args_%s_%d%s" % (nm, args, class_suffix), enum_specializer
 
 def generate_class_template(args, ret = False, member = True):
     print "// %d arguments --"%args
 
-    class_name = runnable_class_name(args, ret, member)
+    class_name, specializer = runnable_class_name(args, ret, member)
+    base_class = "detail::runnable_args_base<%s>" % specializer
 
     if not ret:
-        print "template<"+ gen_typenames(args, member) + "> class %s : public runnable_args_base {" % class_name
+        print "template<"+ gen_typenames(args, member) + "> class %s : public %s {" % (class_name, base_class)
     else:
-        print "template<"+ gen_typenames(args, member) + ", typename R> class %s : public runnable_args_base {" % class_name
+        print "template<"+ gen_typenames(args, member) + ", typename R> class %s : public %s {" % (class_name, base_class)
 
     print " public:"
 
     if not ret:
         print "  %s(" % class_name + gen_args_type(args, member) + ") :"
         print "    " + gen_init(args, False, member) + "  {}"
     else:
         print "  %s(" % class_name + gen_args_type(args, member) + ", R *r) :"
         print "    " + gen_init(args, True, member) + "  {}"
-        print "  virtual bool returns_value() const { return true; }"
     print
     print "  NS_IMETHOD Run() {"
     if ret:
         print "    *r_ =",
     else:
         print "   ",
     if member:
         print "((*o_).*m_)(" + gen_args_(args) + ");"
@@ -129,33 +131,33 @@ def generate_class_template(args, ret = 
     print
 
 def generate_function_template(args, member):
     if member:
         NM = "";
     else:
         NM = "NM";
 
-    class_name = runnable_class_name(args, False, member)
+    class_name, _ = runnable_class_name(args, False, member)
 
     print "// %d arguments --"%args
     print "template<" + gen_typenames(args, member) + ">"
     print "%s<" % class_name + gen_types(args, member) + ">* WrapRunnable%s("%NM + gen_args_type(args, member) + ") {"
     print "  return new %s<" % class_name + gen_types(args, member) + ">"
     print "    (" + gen_args(args, member) + ");"
     print "}"
     print
 
 def generate_function_template_ret(args, member):
     if member:
         NM = "";
     else:
         NM = "NM";
 
-    class_name = runnable_class_name(args, True, member)
+    class_name, _ = runnable_class_name(args, True, member)
 
     print "// %d arguments --"%args
     print "template<" + gen_typenames(args, member) + ", typename R>"
     print "%s<" % class_name + gen_types(args, member) + ", R>* WrapRunnable%sRet("%NM + gen_args_type(args, member) + ", R* r) {"
     print "  return new %s<" % class_name + gen_types(args, member) + ", R>"
     print "    (" + gen_args(args, member) + ", r);"
     print "}"
     print
--- a/media/mtransport/runnable_utils_generated.h
+++ b/media/mtransport/runnable_utils_generated.h
@@ -1,51 +1,50 @@
 /* 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/. */
 
 
 // 0 arguments --
-template<typename M> class runnable_args_nm_0 : public runnable_args_base {
+template<typename M> class runnable_args_nm_0 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_0(M m) :
     m_(m)  {}
 
   NS_IMETHOD Run() {
     m_();
     return NS_OK;
   }
 
  private:
   M m_;
 };
 
 
 
 // 0 arguments --
-template<typename M, typename R> class runnable_args_nm_0_ret : public runnable_args_base {
+template<typename M, typename R> class runnable_args_nm_0_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_0_ret(M m, R *r) :
     m_(m), r_(r)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_();
     return NS_OK;
   }
 
  private:
   M m_;
   R* r_;
 };
 
 
 
 // 0 arguments --
-template<typename C, typename M> class runnable_args_m_0 : public runnable_args_base {
+template<typename C, typename M> class runnable_args_m_0 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_0(C o, M m) :
     o_(o), m_(m)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)();
     return NS_OK;
   }
@@ -53,37 +52,36 @@ template<typename C, typename M> class r
  private:
   C o_;
   M m_;
 };
 
 
 
 // 0 arguments --
-template<typename C, typename M, typename R> class runnable_args_m_0_ret : public runnable_args_base {
+template<typename C, typename M, typename R> class runnable_args_m_0_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_0_ret(C o, M m, R *r) :
     o_(o), m_(m), r_(r)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)();
     return NS_OK;
   }
 
  private:
   C o_;
   M m_;
   R* r_;
 };
 
 
 
 // 1 arguments --
-template<typename M, typename A0> class runnable_args_nm_1 : public runnable_args_base {
+template<typename M, typename A0> class runnable_args_nm_1 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_1(M m, A0 a0) :
     m_(m), a0_(a0)  {}
 
   NS_IMETHOD Run() {
     m_(a0_);
     return NS_OK;
   }
@@ -91,37 +89,36 @@ template<typename M, typename A0> class 
  private:
   M m_;
   A0 a0_;
 };
 
 
 
 // 1 arguments --
-template<typename M, typename A0, typename R> class runnable_args_nm_1_ret : public runnable_args_base {
+template<typename M, typename A0, typename R> class runnable_args_nm_1_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_1_ret(M m, A0 a0, R *r) :
     m_(m), r_(r), a0_(a0)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_);
     return NS_OK;
   }
 
  private:
   M m_;
   R* r_;
   A0 a0_;
 };
 
 
 
 // 1 arguments --
-template<typename C, typename M, typename A0> class runnable_args_m_1 : public runnable_args_base {
+template<typename C, typename M, typename A0> class runnable_args_m_1 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_1(C o, M m, A0 a0) :
     o_(o), m_(m), a0_(a0)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_);
     return NS_OK;
   }
@@ -130,38 +127,37 @@ template<typename C, typename M, typenam
   C o_;
   M m_;
   A0 a0_;
 };
 
 
 
 // 1 arguments --
-template<typename C, typename M, typename A0, typename R> class runnable_args_m_1_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename R> class runnable_args_m_1_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_1_ret(C o, M m, A0 a0, R *r) :
     o_(o), m_(m), r_(r), a0_(a0)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_);
     return NS_OK;
   }
 
  private:
   C o_;
   M m_;
   R* r_;
   A0 a0_;
 };
 
 
 
 // 2 arguments --
-template<typename M, typename A0, typename A1> class runnable_args_nm_2 : public runnable_args_base {
+template<typename M, typename A0, typename A1> class runnable_args_nm_2 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_2(M m, A0 a0, A1 a1) :
     m_(m), a0_(a0), a1_(a1)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_);
     return NS_OK;
   }
@@ -170,38 +166,37 @@ template<typename M, typename A0, typena
   M m_;
   A0 a0_;
   A1 a1_;
 };
 
 
 
 // 2 arguments --
-template<typename M, typename A0, typename A1, typename R> class runnable_args_nm_2_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename R> class runnable_args_nm_2_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_2_ret(M m, A0 a0, A1 a1, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_);
     return NS_OK;
   }
 
  private:
   M m_;
   R* r_;
   A0 a0_;
   A1 a1_;
 };
 
 
 
 // 2 arguments --
-template<typename C, typename M, typename A0, typename A1> class runnable_args_m_2 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1> class runnable_args_m_2 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_2(C o, M m, A0 a0, A1 a1) :
     o_(o), m_(m), a0_(a0), a1_(a1)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_);
     return NS_OK;
   }
@@ -211,21 +206,20 @@ template<typename C, typename M, typenam
   M m_;
   A0 a0_;
   A1 a1_;
 };
 
 
 
 // 2 arguments --
-template<typename C, typename M, typename A0, typename A1, typename R> class runnable_args_m_2_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename R> class runnable_args_m_2_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_2_ret(C o, M m, A0 a0, A1 a1, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -233,17 +227,17 @@ template<typename C, typename M, typenam
   R* r_;
   A0 a0_;
   A1 a1_;
 };
 
 
 
 // 3 arguments --
-template<typename M, typename A0, typename A1, typename A2> class runnable_args_nm_3 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2> class runnable_args_nm_3 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_3(M m, A0 a0, A1 a1, A2 a2) :
     m_(m), a0_(a0), a1_(a1), a2_(a2)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_);
     return NS_OK;
   }
@@ -253,21 +247,20 @@ template<typename M, typename A0, typena
   A0 a0_;
   A1 a1_;
   A2 a2_;
 };
 
 
 
 // 3 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename R> class runnable_args_nm_3_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename R> class runnable_args_nm_3_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_3_ret(M m, A0 a0, A1 a1, A2 a2, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -275,17 +268,17 @@ template<typename M, typename A0, typena
   A0 a0_;
   A1 a1_;
   A2 a2_;
 };
 
 
 
 // 3 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2> class runnable_args_m_3 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2> class runnable_args_m_3 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_3(C o, M m, A0 a0, A1 a1, A2 a2) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_);
     return NS_OK;
   }
@@ -296,21 +289,20 @@ template<typename C, typename M, typenam
   A0 a0_;
   A1 a1_;
   A2 a2_;
 };
 
 
 
 // 3 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename R> class runnable_args_m_3_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename R> class runnable_args_m_3_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_3_ret(C o, M m, A0 a0, A1 a1, A2 a2, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -319,17 +311,17 @@ template<typename C, typename M, typenam
   A0 a0_;
   A1 a1_;
   A2 a2_;
 };
 
 
 
 // 4 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3> class runnable_args_nm_4 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3> class runnable_args_nm_4 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_4(M m, A0 a0, A1 a1, A2 a2, A3 a3) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_);
     return NS_OK;
   }
@@ -340,21 +332,20 @@ template<typename M, typename A0, typena
   A1 a1_;
   A2 a2_;
   A3 a3_;
 };
 
 
 
 // 4 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename R> class runnable_args_nm_4_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename R> class runnable_args_nm_4_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_4_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -363,17 +354,17 @@ template<typename M, typename A0, typena
   A1 a1_;
   A2 a2_;
   A3 a3_;
 };
 
 
 
 // 4 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3> class runnable_args_m_4 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3> class runnable_args_m_4 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_4(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_);
     return NS_OK;
   }
@@ -385,21 +376,20 @@ template<typename C, typename M, typenam
   A1 a1_;
   A2 a2_;
   A3 a3_;
 };
 
 
 
 // 4 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename R> class runnable_args_m_4_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename R> class runnable_args_m_4_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_4_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -409,17 +399,17 @@ template<typename C, typename M, typenam
   A1 a1_;
   A2 a2_;
   A3 a3_;
 };
 
 
 
 // 5 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4> class runnable_args_nm_5 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4> class runnable_args_nm_5 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_5(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_, a4_);
     return NS_OK;
   }
@@ -431,21 +421,20 @@ template<typename M, typename A0, typena
   A2 a2_;
   A3 a3_;
   A4 a4_;
 };
 
 
 
 // 5 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename R> class runnable_args_nm_5_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename R> class runnable_args_nm_5_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_5_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_, a4_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -455,17 +444,17 @@ template<typename M, typename A0, typena
   A2 a2_;
   A3 a3_;
   A4 a4_;
 };
 
 
 
 // 5 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4> class runnable_args_m_5 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4> class runnable_args_m_5 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_5(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_);
     return NS_OK;
   }
@@ -478,21 +467,20 @@ template<typename C, typename M, typenam
   A2 a2_;
   A3 a3_;
   A4 a4_;
 };
 
 
 
 // 5 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename R> class runnable_args_m_5_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename R> class runnable_args_m_5_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_5_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -503,17 +491,17 @@ template<typename C, typename M, typenam
   A2 a2_;
   A3 a3_;
   A4 a4_;
 };
 
 
 
 // 6 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> class runnable_args_nm_6 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> class runnable_args_nm_6 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_6(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_, a4_, a5_);
     return NS_OK;
   }
@@ -526,21 +514,20 @@ template<typename M, typename A0, typena
   A3 a3_;
   A4 a4_;
   A5 a5_;
 };
 
 
 
 // 6 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename R> class runnable_args_nm_6_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename R> class runnable_args_nm_6_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_6_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -551,17 +538,17 @@ template<typename M, typename A0, typena
   A3 a3_;
   A4 a4_;
   A5 a5_;
 };
 
 
 
 // 6 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> class runnable_args_m_6 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> class runnable_args_m_6 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_6(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_);
     return NS_OK;
   }
@@ -575,21 +562,20 @@ template<typename C, typename M, typenam
   A3 a3_;
   A4 a4_;
   A5 a5_;
 };
 
 
 
 // 6 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename R> class runnable_args_m_6_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename R> class runnable_args_m_6_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_6_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -601,17 +587,17 @@ template<typename C, typename M, typenam
   A3 a3_;
   A4 a4_;
   A5 a5_;
 };
 
 
 
 // 7 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> class runnable_args_nm_7 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> class runnable_args_nm_7 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_7(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_);
     return NS_OK;
   }
@@ -625,21 +611,20 @@ template<typename M, typename A0, typena
   A4 a4_;
   A5 a5_;
   A6 a6_;
 };
 
 
 
 // 7 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename R> class runnable_args_nm_7_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename R> class runnable_args_nm_7_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_7_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -651,17 +636,17 @@ template<typename M, typename A0, typena
   A4 a4_;
   A5 a5_;
   A6 a6_;
 };
 
 
 
 // 7 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> class runnable_args_m_7 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> class runnable_args_m_7 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_7(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_);
     return NS_OK;
   }
@@ -676,21 +661,20 @@ template<typename C, typename M, typenam
   A4 a4_;
   A5 a5_;
   A6 a6_;
 };
 
 
 
 // 7 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename R> class runnable_args_m_7_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename R> class runnable_args_m_7_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_7_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -703,17 +687,17 @@ template<typename C, typename M, typenam
   A4 a4_;
   A5 a5_;
   A6 a6_;
 };
 
 
 
 // 8 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> class runnable_args_nm_8 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> class runnable_args_nm_8 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_8(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
     return NS_OK;
   }
@@ -728,21 +712,20 @@ template<typename M, typename A0, typena
   A5 a5_;
   A6 a6_;
   A7 a7_;
 };
 
 
 
 // 8 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename R> class runnable_args_nm_8_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename R> class runnable_args_nm_8_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_8_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -755,17 +738,17 @@ template<typename M, typename A0, typena
   A5 a5_;
   A6 a6_;
   A7 a7_;
 };
 
 
 
 // 8 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> class runnable_args_m_8 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> class runnable_args_m_8 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_8(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
     return NS_OK;
   }
@@ -781,21 +764,20 @@ template<typename C, typename M, typenam
   A5 a5_;
   A6 a6_;
   A7 a7_;
 };
 
 
 
 // 8 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename R> class runnable_args_m_8_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename R> class runnable_args_m_8_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_8_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -809,17 +791,17 @@ template<typename C, typename M, typenam
   A5 a5_;
   A6 a6_;
   A7 a7_;
 };
 
 
 
 // 9 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> class runnable_args_nm_9 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> class runnable_args_nm_9 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_9(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_);
     return NS_OK;
   }
@@ -835,21 +817,20 @@ template<typename M, typename A0, typena
   A6 a6_;
   A7 a7_;
   A8 a8_;
 };
 
 
 
 // 9 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename R> class runnable_args_nm_9_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename R> class runnable_args_nm_9_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_9_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -863,17 +844,17 @@ template<typename M, typename A0, typena
   A6 a6_;
   A7 a7_;
   A8 a8_;
 };
 
 
 
 // 9 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> class runnable_args_m_9 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> class runnable_args_m_9 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_9(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_);
     return NS_OK;
   }
@@ -890,21 +871,20 @@ template<typename C, typename M, typenam
   A6 a6_;
   A7 a7_;
   A8 a8_;
 };
 
 
 
 // 9 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename R> class runnable_args_m_9_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename R> class runnable_args_m_9_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_9_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -919,17 +899,17 @@ template<typename C, typename M, typenam
   A6 a6_;
   A7 a7_;
   A8 a8_;
 };
 
 
 
 // 10 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> class runnable_args_nm_10 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> class runnable_args_nm_10 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_10(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
     return NS_OK;
   }
@@ -946,21 +926,20 @@ template<typename M, typename A0, typena
   A7 a7_;
   A8 a8_;
   A9 a9_;
 };
 
 
 
 // 10 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R> class runnable_args_nm_10_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R> class runnable_args_nm_10_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_10_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -975,17 +954,17 @@ template<typename M, typename A0, typena
   A7 a7_;
   A8 a8_;
   A9 a9_;
 };
 
 
 
 // 10 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> class runnable_args_m_10 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> class runnable_args_m_10 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_10(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
     return NS_OK;
   }
@@ -1003,21 +982,20 @@ template<typename C, typename M, typenam
   A7 a7_;
   A8 a8_;
   A9 a9_;
 };
 
 
 
 // 10 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R> class runnable_args_m_10_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R> class runnable_args_m_10_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_10_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -1033,17 +1011,17 @@ template<typename C, typename M, typenam
   A7 a7_;
   A8 a8_;
   A9 a9_;
 };
 
 
 
 // 11 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> class runnable_args_nm_11 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> class runnable_args_nm_11 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_11(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
     return NS_OK;
   }
@@ -1061,21 +1039,20 @@ template<typename M, typename A0, typena
   A8 a8_;
   A9 a9_;
   A10 a10_;
 };
 
 
 
 // 11 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R> class runnable_args_nm_11_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R> class runnable_args_nm_11_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_11_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -1091,17 +1068,17 @@ template<typename M, typename A0, typena
   A8 a8_;
   A9 a9_;
   A10 a10_;
 };
 
 
 
 // 11 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> class runnable_args_m_11 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> class runnable_args_m_11 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_11(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
     return NS_OK;
   }
@@ -1120,21 +1097,20 @@ template<typename C, typename M, typenam
   A8 a8_;
   A9 a9_;
   A10 a10_;
 };
 
 
 
 // 11 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R> class runnable_args_m_11_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R> class runnable_args_m_11_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_11_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -1151,17 +1127,17 @@ template<typename C, typename M, typenam
   A8 a8_;
   A9 a9_;
   A10 a10_;
 };
 
 
 
 // 12 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11> class runnable_args_nm_12 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11> class runnable_args_nm_12 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_12(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
     return NS_OK;
   }
@@ -1180,21 +1156,20 @@ template<typename M, typename A0, typena
   A9 a9_;
   A10 a10_;
   A11 a11_;
 };
 
 
 
 // 12 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R> class runnable_args_nm_12_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R> class runnable_args_nm_12_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_12_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -1211,17 +1186,17 @@ template<typename M, typename A0, typena
   A9 a9_;
   A10 a10_;
   A11 a11_;
 };
 
 
 
 // 12 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11> class runnable_args_m_12 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11> class runnable_args_m_12 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_12(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
     return NS_OK;
   }
@@ -1241,21 +1216,20 @@ template<typename C, typename M, typenam
   A9 a9_;
   A10 a10_;
   A11 a11_;
 };
 
 
 
 // 12 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R> class runnable_args_m_12_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R> class runnable_args_m_12_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_12_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -1273,17 +1247,17 @@ template<typename C, typename M, typenam
   A9 a9_;
   A10 a10_;
   A11 a11_;
 };
 
 
 
 // 13 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12> class runnable_args_nm_13 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12> class runnable_args_nm_13 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_13(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
     return NS_OK;
   }
@@ -1303,21 +1277,20 @@ template<typename M, typename A0, typena
   A10 a10_;
   A11 a11_;
   A12 a12_;
 };
 
 
 
 // 13 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R> class runnable_args_nm_13_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R> class runnable_args_nm_13_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_13_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -1335,17 +1308,17 @@ template<typename M, typename A0, typena
   A10 a10_;
   A11 a11_;
   A12 a12_;
 };
 
 
 
 // 13 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12> class runnable_args_m_13 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12> class runnable_args_m_13 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_13(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
     return NS_OK;
   }
@@ -1366,21 +1339,20 @@ template<typename C, typename M, typenam
   A10 a10_;
   A11 a11_;
   A12 a12_;
 };
 
 
 
 // 13 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R> class runnable_args_m_13_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R> class runnable_args_m_13_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_13_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
     return NS_OK;
   }
 
  private:
   C o_;
@@ -1399,17 +1371,17 @@ template<typename C, typename M, typenam
   A10 a10_;
   A11 a11_;
   A12 a12_;
 };
 
 
 
 // 14 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13> class runnable_args_nm_14 : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13> class runnable_args_nm_14 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_nm_14(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) :
     m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13)  {}
 
   NS_IMETHOD Run() {
     m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
     return NS_OK;
   }
@@ -1430,21 +1402,20 @@ template<typename M, typename A0, typena
   A11 a11_;
   A12 a12_;
   A13 a13_;
 };
 
 
 
 // 14 arguments --
-template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R> class runnable_args_nm_14_ret : public runnable_args_base {
+template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R> class runnable_args_nm_14_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_nm_14_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, R *r) :
     m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
     return NS_OK;
   }
 
  private:
   M m_;
@@ -1463,17 +1434,17 @@ template<typename M, typename A0, typena
   A11 a11_;
   A12 a12_;
   A13 a13_;
 };
 
 
 
 // 14 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13> class runnable_args_m_14 : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13> class runnable_args_m_14 : public detail::runnable_args_base<detail::NoResult> {
  public:
   runnable_args_m_14(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) :
     o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13)  {}
 
   NS_IMETHOD Run() {
     ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
     return NS_OK;
   }
@@ -1495,21 +1466,20 @@ template<typename C, typename M, typenam
   A11 a11_;
   A12 a12_;
   A13 a13_;
 };
 
 
 
 // 14 arguments --
-template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R> class runnable_args_m_14_ret : public runnable_args_base {
+template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R> class runnable_args_m_14_ret : public detail::runnable_args_base<detail::ReturnsResult> {
  public:
   runnable_args_m_14_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, R *r) :
     o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13)  {}
-  virtual bool returns_value() const { return true; }
 
   NS_IMETHOD Run() {
     *r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
     return NS_OK;
   }
 
  private:
   C o_;
--- a/media/mtransport/test/ice_unittest.cpp
+++ b/media/mtransport/test/ice_unittest.cpp
@@ -243,18 +243,17 @@ class IceTestPeer : public sigslot::has_
     return ice_ctx_->GetGlobalAttributes();
   }
 
    std::vector<std::string> GetCandidates(size_t stream) {
     std::vector<std::string> v;
 
     RUN_ON_THREAD(
         test_utils->sts_target(),
-        WrapRunnableRet(this, &IceTestPeer::GetCandidates_s, stream, &v),
-        NS_DISPATCH_SYNC);
+        WrapRunnableRet(this, &IceTestPeer::GetCandidates_s, stream, &v));
 
     return v;
   }
 
   std::vector<std::string> GetCandidates_s(size_t stream) {
     std::vector<std::string> candidates;
 
     if (stream >= streams_.size())
--- a/media/mtransport/test/transport_unittests.cpp
+++ b/media/mtransport/test/transport_unittests.cpp
@@ -361,18 +361,17 @@ class TransportTestPeer : public sigslot
   void SetLoss(uint32_t loss) {
     lossy_->SetLoss(loss);
   }
 
   TransportLayer::State state() {
     TransportLayer::State tstate;
 
     RUN_ON_THREAD(test_utils->sts_target(),
-                  WrapRunnableRet(flow_, &TransportFlow::state, &tstate),
-                  NS_DISPATCH_SYNC);
+                  WrapRunnableRet(flow_, &TransportFlow::state, &tstate));
 
     return tstate;
   }
 
   bool connected() {
     return state() == TransportLayer::TS_OPEN;
   }