Bug 957256: Modify StartupCache callbacks to use context parameter to obtain object pointer; r=bsmedberg
authorAaron Klotz <aklotz@mozilla.com>
Fri, 10 Jan 2014 17:16:25 -0700
changeset 179028 3f8990e34520df619b8219353b05e825f8dcc1a1
parent 179027 30d5d70de548a2e1726dd7010482cfbd62d04d9b
child 179029 5cae5d9ef313aded50e3ed3023a07afdd73f6cd0
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs957256
milestone29.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 957256: Modify StartupCache callbacks to use context parameter to obtain object pointer; r=bsmedberg
startupcache/StartupCache.cpp
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -140,17 +140,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
@@ -531,34 +531,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 char16_t* data)