Bug 957256 - Modify StartupCache callbacks to use context parameter to obtain object pointer. r=bsmedberg, a=lsblakk
authorAaron Klotz <aklotz@mozilla.com>
Fri, 10 Jan 2014 17:16:25 -0700
changeset 175799 a15b1eecd003a275902f475fcda5913ee5b7b9ff
parent 175798 9734d99bf243ab24d47dd9d834bf25f01e74a2d1
child 175800 979e501cd374a172cd2b82b46c8a48239e1ea9fd
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, lsblakk
bugs957256
milestone28.0a2
Bug 957256 - Modify StartupCache callbacks to use context parameter to obtain object pointer. r=bsmedberg, a=lsblakk
startupcache/StartupCache.cpp
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -138,17 +138,17 @@ StartupCache::~StartupCache()
   // Generally, the in-memory table should be empty here,
   // but an early shutdown means either mTimer didn't run
   // or the write thread is still running.
   WaitOnWriteThread();
 
   // If we shutdown quickly timer wont have fired. Instead of writing
   // it on the main thread and block the shutdown we simply wont update
   // the startup cache. Always do this if the file doesn't exist since
-  // we use it part of the packge step.
+  // we use it part of the package step.
   if (!mArchive) {
     WriteToDisk();
   }
 
   UnregisterWeakMemoryReporter(this);
 }
 
 nsresult
@@ -529,34 +529,50 @@ StartupCache::WaitOnWriteThread()
   PR_JoinThread(mWriteThread);
   mWriteThread = nullptr;
 }
 
 void
 StartupCache::ThreadedWrite(void *aClosure)
 {
   PR_SetCurrentThreadName("StartupCache");
-  gStartupCache->WriteToDisk();
+  /*
+   * It is safe to use the pointer passed in aClosure to reference the
+   * StartupCache object because the thread's lifetime is tightly coupled to
+   * the lifetime of the StartupCache object; this thread is joined in the
+   * StartupCache destructor, guaranteeing that this function runs if and only
+   * if the StartupCache object is valid.
+   */
+  StartupCache* startupCacheObj = static_cast<StartupCache*>(aClosure);
+  startupCacheObj->WriteToDisk();
 }
 
 /*
  * The write-thread is spawned on a timeout(which is reset with every write). This
  * can avoid a slow shutdown. After writing out the cache, the zipreader is
  * reloaded on the worker thread.
  */
 void
 StartupCache::WriteTimeout(nsITimer *aTimer, void *aClosure)
 {
-  gStartupCache->mWriteThread = PR_CreateThread(PR_USER_THREAD,
-                                                StartupCache::ThreadedWrite,
-                                                nullptr,
-                                                PR_PRIORITY_NORMAL,
-                                                PR_LOCAL_THREAD,
-                                                PR_JOINABLE_THREAD,
-                                                0);
+  /*
+   * It is safe to use the pointer passed in aClosure to reference the
+   * StartupCache object because the timer's lifetime is tightly coupled to
+   * the lifetime of the StartupCache object; this timer is canceled in the
+   * StartupCache destructor, guaranteeing that this function runs if and only
+   * if the StartupCache object is valid.
+   */
+  StartupCache* startupCacheObj = static_cast<StartupCache*>(aClosure);
+  startupCacheObj->mWriteThread = PR_CreateThread(PR_USER_THREAD,
+                                                  StartupCache::ThreadedWrite,
+                                                  startupCacheObj,
+                                                  PR_PRIORITY_NORMAL,
+                                                  PR_LOCAL_THREAD,
+                                                  PR_JOINABLE_THREAD,
+                                                  0);
 }
 
 // We don't want to refcount StartupCache, so we'll just
 // hold a ref to this and pass it to observerService instead.
 NS_IMPL_ISUPPORTS1(StartupCacheListener, nsIObserver)
 
 nsresult
 StartupCacheListener::Observe(nsISupports *subject, const char* topic, const PRUnichar* data)