Bug 1024765 - Part 1: Add test case for timers firing when the target thread is not running. r=bwc
authorByron Campen [:bwc] <docfaraday@gmail.com>
Tue, 17 Jun 2014 13:37:04 -0700
changeset 190160 2210c3fbcf6306fac25a12a49d75ff45286ce05a
parent 190159 72c2544c167d51111e49d64c5975987560678900
child 190161 0c09da2ef5468437db4a38823c692ff5769f1a67
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbwc
bugs1024765
milestone33.0a1
Bug 1024765 - Part 1: Add test case for timers firing when the target thread is not running. r=bwc
xpcom/tests/TestTimers.cpp
--- a/xpcom/tests/TestTimers.cpp
+++ b/xpcom/tests/TestTimers.cpp
@@ -9,16 +9,17 @@
 #include "nsITimer.h"
 
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "prinrval.h"
 #include "prmon.h"
+#include "prthread.h"
 #include "mozilla/Attributes.h"
 
 #include "mozilla/ReentrantMonitor.h"
 using namespace mozilla;
 
 typedef nsresult(*TestFuncPtr)();
 
 class AutoTestThread
@@ -73,16 +74,17 @@ class TimerCallback MOZ_FINAL : public n
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   TimerCallback(nsIThread** aThreadPtr, ReentrantMonitor* aReentrantMonitor)
   : mThreadPtr(aThreadPtr), mReentrantMonitor(aReentrantMonitor) { }
 
   NS_IMETHOD Notify(nsITimer* aTimer) {
+    NS_ASSERTION(mThreadPtr, "Callback was not supposed to be called!");
     nsCOMPtr<nsIThread> current(do_GetCurrentThread());
 
     ReentrantMonitorAutoEnter mon(*mReentrantMonitor);
 
     NS_ASSERTION(!*mThreadPtr, "Timer called back more than once!");
     *mThreadPtr = current;
 
     mon.Notify();
@@ -128,23 +130,55 @@ TestTargetedTimers()
   while (!notifiedThread) {
     mon.Wait();
   }
   NS_ENSURE_TRUE(notifiedThread == testThread, NS_ERROR_FAILURE);
 
   return NS_OK;
 }
 
+nsresult
+TestTimerWithStoppedTarget()
+{
+  AutoTestThread testThread;
+  NS_ENSURE_TRUE(testThread, NS_ERROR_OUT_OF_MEMORY);
+
+  nsresult rv;
+  nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsIEventTarget* target = static_cast<nsIEventTarget*>(testThread);
+
+  rv = timer->SetTarget(target);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // If this is called, we'll assert
+  nsCOMPtr<nsITimerCallback> callback =
+    new TimerCallback(nullptr, nullptr);
+  NS_ENSURE_TRUE(callback, NS_ERROR_OUT_OF_MEMORY);
+
+  rv = timer->InitWithCallback(callback, PR_MillisecondsToInterval(100),
+                               nsITimer::TYPE_ONE_SHOT);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  testThread->Shutdown();
+
+  PR_Sleep(400);
+
+  return NS_OK;
+}
+
 int main(int argc, char** argv)
 {
   ScopedXPCOM xpcom("TestTimers");
   NS_ENSURE_FALSE(xpcom.failed(), 1);
 
   static TestFuncPtr testsToRun[] = {
-    TestTargetedTimers
+    TestTargetedTimers,
+    TestTimerWithStoppedTarget
   };
   static uint32_t testCount = sizeof(testsToRun) / sizeof(testsToRun[0]);
 
   for (uint32_t i = 0; i < testCount; i++) {
     nsresult rv = testsToRun[i]();
     NS_ENSURE_SUCCESS(rv, 1);
   }