Bug 753461 - Write shutdown time to disk. r=taras.
authorRafael Ávila de Espíndola <respindola@mozilla.com>
Fri, 18 May 2012 08:13:30 -0400
changeset 94362 c2e8a029913d2b986cd406a2ab39f7f3292b88c1
parent 94361 9901a0253c6396910ccc29db3e65945eb6eb7490
child 94363 e917972dc75df6f08f86506c0bbc99c02b94f1f5
push id22712
push userryanvm@gmail.com
push dateSat, 19 May 2012 00:52:01 +0000
treeherdermozilla-central@642d1a36702f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstaras
bugs753461
milestone15.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 753461 - Write shutdown time to disk. r=taras.
toolkit/components/startup/nsAppStartup.cpp
--- a/toolkit/components/startup/nsAppStartup.cpp
+++ b/toolkit/components/startup/nsAppStartup.cpp
@@ -73,16 +73,17 @@
 #include "nsWidgetsCID.h"
 #include "nsAppShellCID.h"
 #include "nsXPCOMCIDInternal.h"
 #include "mozilla/Services.h"
 #include "mozilla/FunctionTimer.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 #include "prenv.h"
+#include "nsAppDirectoryServiceDefs.h"
 
 #if defined(XP_WIN)
 #include <windows.h>
 // windows.h can go to hell 
 #undef GetStartupInfo
 #elif defined(XP_UNIX)
 #include <unistd.h>
 #include <sys/syscall.h>
@@ -295,31 +296,97 @@ nsAppStartup::Run(void)
     nsresult rv = mAppShell->Run();
     if (NS_FAILED(rv))
       return rv;
   }
 
   return mRestart ? NS_SUCCESS_RESTART_APP : NS_OK;
 }
 
+static TimeStamp gRecordedShutdownStartTime;
+static char *gRecordedShutdownTimeFileName = NULL;
+
+static void
+RecordShutdownStartTimeStamp() {
+  if (!Telemetry::CanRecord())
+    return;
+
+  gRecordedShutdownStartTime = TimeStamp::Now();
+
+  nsCOMPtr<nsIFile> mozFile;
+  NS_GetSpecialDirectory(NS_APP_PREFS_50_DIR, getter_AddRefs(mozFile));
+  if (!mozFile)
+    return;
+
+  mozFile->AppendNative(NS_LITERAL_CSTRING("Telemetry.ShutdownTime.txt"));
+  nsCAutoString nativePath;
+  nsresult rv = mozFile->GetNativePath(nativePath);
+  if (!NS_SUCCEEDED(rv))
+    return;
+
+  gRecordedShutdownTimeFileName = PL_strdup(nativePath.get());
+}
+
+static void
+RecordShutdownEndTimeStamp() {
+  if (!gRecordedShutdownTimeFileName)
+    return;
+
+  nsCString name(gRecordedShutdownTimeFileName);
+  PL_strfree(gRecordedShutdownTimeFileName);
+  gRecordedShutdownTimeFileName = NULL;
+
+  nsCString tmpName = name;
+  tmpName += ".tmp";
+  PRFileDesc *f = PR_Open(tmpName.get(), PR_CREATE_FILE | PR_WRONLY,
+                          PR_IRUSR | PR_IWUSR);
+  if (!f)
+    return;
+
+  TimeStamp now = TimeStamp::Now();
+  MOZ_ASSERT(now >= gRecordedShutdownStartTime);
+  TimeDuration diff = now - gRecordedShutdownStartTime;
+  uint32_t diff2 = diff.ToMilliseconds();
+  uint32_t written = PR_fprintf(f, "%d\n", diff2);
+  PRStatus rv = PR_Close(f);
+  if (written == static_cast<uint32_t>(-1) || rv != PR_SUCCESS) {
+    PR_Delete(tmpName.get());
+    return;
+  }
+  PR_Rename(tmpName.get(), name.get());
+}
+
+// For now firefox runs static destructors during shutdown on release builds
+// too, so we just use one to run RecordShutdownEndTimeStamp. Once we are
+// exiting earlier in release builds we just move the call.
+class RecordShutdownEndTimeStampHelper {
+public:
+  ~RecordShutdownEndTimeStampHelper() {
+    RecordShutdownEndTimeStamp();
+  }
+};
+
+static RecordShutdownEndTimeStampHelper gHelper;
 
 NS_IMETHODIMP
 nsAppStartup::Quit(uint32_t aMode)
 {
   uint32_t ferocity = (aMode & 0xF);
 
   // Quit the application. We will asynchronously call the appshell's
   // Exit() method via nsAppExitEvent to allow one last pass
   // through any events in the queue. This guarantees a tidy cleanup.
   nsresult rv = NS_OK;
   bool postedExitEvent = false;
 
   if (mShuttingDown)
     return NS_OK;
 
+  RecordShutdownStartTimeStamp();
+
   // If we're considering quitting, we will only do so if:
   if (ferocity == eConsiderQuit) {
     if (mConsiderQuitStopper == 0) {
       // there are no windows...
       ferocity = eAttemptQuit;
     }
 #ifdef XP_MACOSX
     else if (mConsiderQuitStopper == 1) {