Bug 1268313: Part 5 - Make NS_NewRunnableMethod able to call const functions. r=froydnj
☠☠ backed out by 4bd91d8dd4f5 ☠ ☠
authorKyle Huey <khuey@kylehuey.com>
Thu, 28 Apr 2016 14:08:24 -0700
changeset 357671 726f7361e0b84942ebcdecf78a2d5296748627f9
parent 357670 6a8d57e8fa8ea2875af089cea0971fc5b6c4f60c
child 357672 4bcb784492bb8d26a13a234cdf581b0badbf21e6
push id16816
push userbmo:gasolin@mozilla.com
push dateFri, 29 Apr 2016 03:33:20 +0000
reviewersfroydnj
bugs1268313
milestone49.0a1
Bug 1268313: Part 5 - Make NS_NewRunnableMethod able to call const functions. r=froydnj
xpcom/glue/nsThreadUtils.h
xpcom/tests/TestThreadUtils.cpp
--- a/xpcom/glue/nsThreadUtils.h
+++ b/xpcom/glue/nsThreadUtils.h
@@ -337,16 +337,25 @@ template<class C, typename R, bool Ownin
 struct nsRunnableMethodTraits<R(C::*)(As...), Owning, Cancelable>
 {
   typedef C class_type;
   typedef R return_type;
   typedef nsRunnableMethod<C, R, Owning, Cancelable> base_type;
   static const bool can_cancel = Cancelable;
 };
 
+template<class C, typename R, bool Owning, bool Cancelable, typename... As>
+struct nsRunnableMethodTraits<R(C::*)(As...) const, Owning, Cancelable>
+{
+  typedef const C class_type;
+  typedef R return_type;
+  typedef nsRunnableMethod<C, R, Owning, Cancelable> base_type;
+  static const bool can_cancel = Cancelable;
+};
+
 #ifdef NS_HAVE_STDCALL
 template<class C, typename R, bool Owning, bool Cancelable, typename... As>
 struct nsRunnableMethodTraits<R(__stdcall C::*)(As...), Owning, Cancelable>
 {
   typedef C class_type;
   typedef R return_type;
   typedef nsRunnableMethod<C, R, Owning, Cancelable> base_type;
   static const bool can_cancel = Cancelable;
@@ -355,16 +364,33 @@ struct nsRunnableMethodTraits<R(__stdcal
 template<class C, typename R, bool Owning, bool Cancelable>
 struct nsRunnableMethodTraits<R(NS_STDCALL C::*)(), Owning, Cancelable>
 {
   typedef C class_type;
   typedef R return_type;
   typedef nsRunnableMethod<C, R, Owning, Cancelable> base_type;
   static const bool can_cancel = Cancelable;
 };
+template<class C, typename R, bool Owning, bool Cancelable, typename... As>
+struct nsRunnableMethodTraits<R(__stdcall C::*)(As...) const, Owning, Cancelable>
+{
+  typedef const C class_type;
+  typedef R return_type;
+  typedef nsRunnableMethod<C, R, Owning, Cancelable> base_type;
+  static const bool can_cancel = Cancelable;
+};
+
+template<class C, typename R, bool Owning, bool Cancelable>
+struct nsRunnableMethodTraits<R(NS_STDCALL C::*)() const, Owning, Cancelable>
+{
+  typedef const C class_type;
+  typedef R return_type;
+  typedef nsRunnableMethod<C, R, Owning, Cancelable> base_type;
+  static const bool can_cancel = Cancelable;
+};
 #endif
 
 
 // IsParameterStorageClass<T>::value is true if T is a parameter-storage class
 // that will be recognized by NS_New[NonOwning]RunnableMethodWithArg[s] to
 // force a specific storage&passing strategy (instead of inferring one,
 // see ParameterStorage).
 // When creating a new storage class, add a specialization for it to be
--- a/xpcom/tests/TestThreadUtils.cpp
+++ b/xpcom/tests/TestThreadUtils.cpp
@@ -2,16 +2,17 @@
 * 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/. */
 
 #include "TestHarness.h"
 #include "nsThreadUtils.h"
 
 enum {
   TEST_CALL_VOID_ARG_VOID_RETURN,
+  TEST_CALL_VOID_ARG_VOID_RETURN_CONST,
   TEST_CALL_VOID_ARG_NONVOID_RETURN,
   TEST_CALL_NONVOID_ARG_VOID_RETURN,
   TEST_CALL_NONVOID_ARG_NONVOID_RETURN,
   TEST_CALL_NONVOID_ARG_VOID_RETURN_EXPLICIT,
   TEST_CALL_NONVOID_ARG_NONVOID_RETURN_EXPLICIT,
 #ifdef HAVE_STDCALL
   TEST_STDCALL_VOID_ARG_VOID_RETURN,
   TEST_STDCALL_VOID_ARG_NONVOID_RETURN,
@@ -58,16 +59,19 @@ private:
 
 class nsBar : public nsISupports {
   virtual ~nsBar() {}
 public:
   NS_DECL_ISUPPORTS
   void DoBar1(void) {
     gRunnableExecuted[TEST_CALL_VOID_ARG_VOID_RETURN] = true;
   }
+  void DoBar1Const(void) const {
+    gRunnableExecuted[TEST_CALL_VOID_ARG_VOID_RETURN_CONST] = true;
+  }
   nsresult DoBar2(void) {
     gRunnableExecuted[TEST_CALL_VOID_ARG_NONVOID_RETURN] = true;
     return NS_OK;
   }
   void DoBar3(nsFoo* aFoo) {
     aFoo->DoFoo(&gRunnableExecuted[TEST_CALL_NONVOID_ARG_VOID_RETURN]);
   }
   nsresult DoBar4(nsFoo* aFoo) {
@@ -115,25 +119,27 @@ int main(int argc, char** argv)
   ScopedXPCOM xpcom("ThreadUtils");
   NS_ENSURE_FALSE(xpcom.failed(), 1);
 
   memset(gRunnableExecuted, false, MAX_TESTS * sizeof(bool));
   // Scope the smart ptrs so that the runnables need to hold on to whatever they need
   {
     RefPtr<nsFoo> foo = new nsFoo();
     RefPtr<nsBar> bar = new nsBar();
+    RefPtr<const nsBar> constBar = bar;
 
     // This pointer will be freed at the end of the block
     // Do not dereference this pointer in the runnable method!
     RefPtr<nsFoo> rawFoo = new nsFoo();
 
     // Read only string. Dereferencing in runnable method to check this works.
     char* message = (char*)"Test message";
 
     NS_DispatchToMainThread(NS_NewRunnableMethod(bar, &nsBar::DoBar1));
+    NS_DispatchToMainThread(NS_NewRunnableMethod(constBar, &nsBar::DoBar1Const));
     NS_DispatchToMainThread(NS_NewRunnableMethod(bar, &nsBar::DoBar2));
     NS_DispatchToMainThread(NS_NewRunnableMethodWithArg< RefPtr<nsFoo> >
       (bar, &nsBar::DoBar3, foo));
     NS_DispatchToMainThread(NS_NewRunnableMethodWithArg< RefPtr<nsFoo> >
       (bar, &nsBar::DoBar4, foo));
     NS_DispatchToMainThread(NS_NewRunnableMethodWithArg<nsFoo*>(bar, &nsBar::DoBar5, rawFoo));
     NS_DispatchToMainThread(NS_NewRunnableMethodWithArg<char*>(bar, &nsBar::DoBar6, message));
 #ifdef HAVE_STDCALL