Bug 692255 - Get rid of prefetch files on Windows for faster startup. r=rstrong

This commit is contained in:
Brian R. Bondy
2012-05-27 22:40:48 -04:00
parent 3560f2c802
commit a3bcca99ed
13 changed files with 488 additions and 15 deletions

View File

@@ -26,6 +26,7 @@
#include "nsUnicharUtils.h"
#include "nsIWinTaskbar.h"
#include "nsISupportsPrimitives.h"
#include "nsThreadUtils.h"
#include "windows.h"
#include "shellapi.h"
@@ -52,6 +53,11 @@
#define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1"
// We clear the prefetch files one time after the browser is started after
// 60 seconds. After this is done once we set a pref so this will never happen
// again except in updater code.
#define CLEAR_PREFETCH_TIMEOUT_MS 60000
NS_IMPL_ISUPPORTS2(nsWindowsShellService, nsIWindowsShellService, nsIShellService)
static nsresult
@@ -189,6 +195,16 @@ static SETTING gDDESettings[] = {
{ MAKE_KEY_NAME1("Software\\Classes\\HTTPS", SOD) }
};
#if defined(MOZ_MAINTENANCE_SERVICE)
#define ONLY_SERVICE_LAUNCHING
#include "updatehelper.h"
#include "updatehelper.cpp"
static const char kPrefetchClearedPref[] = "app.update.service.prefetchCleared";
static nsCOMPtr<nsIThread> sThread;
#endif
nsresult
GetHelperPath(nsAutoString& aPath)
{
@@ -908,6 +924,123 @@ nsWindowsShellService::SetDesktopBackgroundColor(PRUint32 aColor)
return regKey->Close();
}
nsWindowsShellService::nsWindowsShellService() :
mCheckedThisSession(false)
{
#if defined(MOZ_MAINTENANCE_SERVICE)
// Check to make sure the service is installed
PRUint32 installed = 0;
nsCOMPtr<nsIWindowsRegKey> regKey =
do_CreateInstance("@mozilla.org/windows-registry-key;1");
if (!regKey ||
NS_FAILED(regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
NS_LITERAL_STRING(
"SOFTWARE\\Mozilla\\MaintenanceService"),
nsIWindowsRegKey::ACCESS_READ |
nsIWindowsRegKey::WOW64_64)) ||
NS_FAILED(regKey->ReadIntValue(NS_LITERAL_STRING("Installed"),
&installed)) ||
!installed) {
return;
}
// check to see if we have attempted to do the one time operation of clearing
// the prefetch.
bool prefetchCleared;
nsCOMPtr<nsIPrefBranch> prefBranch;
nsCOMPtr<nsIPrefService> prefs =
do_GetService(NS_PREFSERVICE_CONTRACTID);
if (!prefs ||
NS_FAILED(prefs->GetBranch(nsnull, getter_AddRefs(prefBranch))) ||
(NS_SUCCEEDED(prefBranch->GetBoolPref(kPrefetchClearedPref,
&prefetchCleared)) &&
prefetchCleared)) {
return;
}
// In a minute after startup is definitely complete, launch the
// service command.
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
if (mTimer) {
mTimer->InitWithFuncCallback(
nsWindowsShellService::LaunchPrefetchClearCommand,
nsnull, CLEAR_PREFETCH_TIMEOUT_MS, nsITimer::TYPE_ONE_SHOT);
}
#endif
}
nsWindowsShellService::~nsWindowsShellService()
{
#if defined(MOZ_MAINTENANCE_SERVICE)
if (mTimer) {
mTimer->Cancel();
mTimer = nsnull;
}
if (sThread) {
sThread->Shutdown();
sThread = nsnull;
}
#endif
}
#if defined(MOZ_MAINTENANCE_SERVICE)
class ClearPrefetchEvent : public nsRunnable {
public:
ClearPrefetchEvent()
{
}
NS_IMETHOD Run()
{
// Start the service command
LPCWSTR updaterServiceArgv[2];
updaterServiceArgv[0] = L"MozillaMaintenance";
updaterServiceArgv[1] = L"clear-prefetch";
// If this command fails, it is not critical as prefetch will be cleared
// on the next software update.
StartServiceCommand(NS_ARRAY_LENGTH(updaterServiceArgv),
updaterServiceArgv);
return NS_OK;
}
};
#endif
/**
* For faster startup we attempt to clear the prefetch if the maintenance
* service is installed. Please see the definition of ClearPrefetch()
* in toolkit/components/maintenanceservice/prefetch.cpp for more info.
* For now the only application that gets prefetch cleaned is Firefox
* since we have not done performance checking for other applications.
* This is done on every update but also there is a one time operation done
* from within the program for first time installs.
*/
#if defined(MOZ_MAINTENANCE_SERVICE)
void
nsWindowsShellService::LaunchPrefetchClearCommand(nsITimer *aTimer, void*)
{
// Make sure we don't call this again from the application, it will be
// called on each application update instead.
nsCOMPtr<nsIPrefBranch> prefBranch;
nsCOMPtr<nsIPrefService> prefs =
do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefs) {
if (NS_SUCCEEDED(prefs->GetBranch(nsnull, getter_AddRefs(prefBranch)))) {
prefBranch->SetBoolPref(kPrefetchClearedPref, true);
}
}
// Starting the sevice can take a bit of time and we don't want to block the
// main thread, so start an event on another thread to handle the operation
NS_NewThread(getter_AddRefs(sThread));
if (sThread) {
nsCOMPtr<nsIRunnable> prefetchEvent = new ClearPrefetchEvent();
sThread->Dispatch(prefetchEvent, NS_DISPATCH_NORMAL);
}
}
#endif
NS_IMETHODIMP
nsWindowsShellService::OpenApplicationWithURI(nsILocalFile* aApplication,
const nsACString& aURI)