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 id27001
push userkwierso@gmail.com
push dateTue, 24 Jun 2014 00:35:42 +0000
treeherdermozilla-central@984cd22ec8c3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwc
bugs1024765
milestone33.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 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);
   }