зеркало из https://github.com/mozilla/pjs.git
Bug 401229: Reduce Extension Manager flushing during startup. r=robstrong
This commit is contained in:
Родитель
165dc509e0
Коммит
34e62d8180
|
@ -177,6 +177,9 @@ var gCheckCompatibility = true;
|
|||
var gCheckUpdateSecurity = true;
|
||||
var gLocale = "en-US";
|
||||
var gFirstRun = false;
|
||||
var gAllowFlush = true;
|
||||
var gDSNeedsFlush = false;
|
||||
var gManifestNeedsFlush = false;
|
||||
|
||||
/**
|
||||
* Valid GUIDs fit this pattern.
|
||||
|
@ -2661,6 +2664,25 @@ ExtensionManager.prototype = {
|
|||
* Clean up on application shutdown to avoid leaks.
|
||||
*/
|
||||
_shutdown: function() {
|
||||
if (!gAllowFlush) {
|
||||
// Something went wrong and there are potentially flushes pending.
|
||||
ERROR("Reached _shutdown and without clearing any pending flushes");
|
||||
try {
|
||||
gAllowFlush = true;
|
||||
if (gManifestNeedsFlush) {
|
||||
gManifestNeedsFlush = false;
|
||||
this._updateManifests(false);
|
||||
}
|
||||
if (gDSNeedsFlush) {
|
||||
gDSNeedsFlush = false;
|
||||
this.datasource.Flush();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
ERROR("Error flushing caches: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
gOS.removeObserver(this, "xpcom-shutdown");
|
||||
|
||||
// Release strongly held services.
|
||||
|
@ -2733,6 +2755,9 @@ ExtensionManager.prototype = {
|
|||
if (this._ensureDatasetIntegrity())
|
||||
isDirty = true;
|
||||
|
||||
// Block attempts to flush for the entire startup
|
||||
gAllowFlush = false;
|
||||
|
||||
// Configure any items that are being installed, uninstalled or upgraded
|
||||
// by being added, removed or modified by another process. We must do this
|
||||
// on every startup since there is no way we can tell if this has happened
|
||||
|
@ -2745,20 +2770,37 @@ ExtensionManager.prototype = {
|
|||
if (PendingOperations.size != 0)
|
||||
isDirty = true;
|
||||
|
||||
var needsRestart = false;
|
||||
// Extension Changes
|
||||
if (isDirty) {
|
||||
var needsRestart = this._finishOperations();
|
||||
needsRestart = this._finishOperations();
|
||||
|
||||
if (forceAutoReg) {
|
||||
this._extensionListChanged = true;
|
||||
needsRestart = true;
|
||||
}
|
||||
return needsRestart;
|
||||
}
|
||||
|
||||
this._startTimers();
|
||||
// Resume flushing and perform a flush for anything that was deferred
|
||||
try {
|
||||
gAllowFlush = true;
|
||||
if (gManifestNeedsFlush) {
|
||||
gManifestNeedsFlush = false;
|
||||
this._updateManifests(false);
|
||||
}
|
||||
if (gDSNeedsFlush) {
|
||||
gDSNeedsFlush = false;
|
||||
this.datasource.Flush();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
ERROR("Error flushing caches: " + e);
|
||||
}
|
||||
|
||||
return false;
|
||||
if (!needsRestart)
|
||||
this._startTimers();
|
||||
|
||||
return needsRestart;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -3568,6 +3610,9 @@ ExtensionManager.prototype = {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Block attempts to flush for the entire startup
|
||||
gAllowFlush = false;
|
||||
|
||||
// Version mismatch, we have to load the extensions datasource and do
|
||||
// version checking. Time hit here doesn't matter since this doesn't happen
|
||||
// all that often.
|
||||
|
@ -3630,6 +3675,11 @@ ExtensionManager.prototype = {
|
|||
else if (allAppManaged)
|
||||
allAppManaged = false;
|
||||
|
||||
var properties = {
|
||||
availableUpdateURL: null,
|
||||
availableUpdateVersion: null
|
||||
};
|
||||
|
||||
if (ds.getItemProperty(id, "providesUpdatesSecurely") == "false") {
|
||||
/* It's possible the previous version did not understand updateKeys so
|
||||
* check if we can import one for this addon from it's manifest. */
|
||||
|
@ -3646,13 +3696,13 @@ ExtensionManager.prototype = {
|
|||
// updates, satisfying its dependencies, and not being blocklisted
|
||||
if (this._isUsableItem(id)) {
|
||||
if (ds.getItemProperty(id, "appDisabled"))
|
||||
ds.setItemProperty(id, EM_R("appDisabled"), null);
|
||||
properties.appDisabled = null;
|
||||
}
|
||||
else if (!ds.getItemProperty(id, "appDisabled")) {
|
||||
properties.appDisabled = EM_L("true");
|
||||
}
|
||||
else if (!ds.getItemProperty(id, "appDisabled"))
|
||||
ds.setItemProperty(id, EM_R("appDisabled"), EM_L("true"));
|
||||
|
||||
ds.setItemProperty(id, EM_R("availableUpdateURL"), null);
|
||||
ds.setItemProperty(id, EM_R("availableUpdateVersion"), null);
|
||||
ds.setItemProperties(id, properties);
|
||||
}
|
||||
|
||||
// Must clean up outside of the loop. Modifying the container while
|
||||
|
@ -3702,6 +3752,23 @@ ExtensionManager.prototype = {
|
|||
|
||||
// Prevent extension update dialog from showing
|
||||
gPref.setBoolPref(PREF_UPDATE_NOTIFYUSER, false);
|
||||
|
||||
// Re-enable flushing and flush anything that was deferred
|
||||
try {
|
||||
gAllowFlush = true;
|
||||
if (gManifestNeedsFlush) {
|
||||
gManifestNeedsFlush = false;
|
||||
this._updateManifests(false);
|
||||
}
|
||||
if (gDSNeedsFlush) {
|
||||
gDSNeedsFlush = false;
|
||||
this.datasource.Flush();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
ERROR("Error flushing caches: " + e);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
@ -3914,10 +3981,20 @@ ExtensionManager.prototype = {
|
|||
* true if the application needs to restart again, false otherwise.
|
||||
*/
|
||||
_updateManifests: function(needsRestart) {
|
||||
// Write the Startup Cache (All Items, visible or not)
|
||||
StartupCache.write();
|
||||
// Write the Extensions Locations Manifest (Visible, enabled items)
|
||||
this._updateExtensionsManifest(needsRestart);
|
||||
// During startup we block flushing until the startup operations are all
|
||||
// complete to reduce file accesses that can trigger bug 431065
|
||||
if (gAllowFlush) {
|
||||
// Write the Startup Cache (All Items, visible or not)
|
||||
StartupCache.write();
|
||||
// Write the Extensions Locations Manifest (Visible, enabled items)
|
||||
this._updateExtensionsManifest();
|
||||
}
|
||||
else {
|
||||
gManifestNeedsFlush = true;
|
||||
}
|
||||
|
||||
// Notify nsAppRunner to update the compatibility manifest on next startup
|
||||
this._extensionListChanged = needsRestart;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -3959,10 +4036,8 @@ ExtensionManager.prototype = {
|
|||
|
||||
/**
|
||||
* Write the Extensions List
|
||||
* @param needsRestart
|
||||
* true if the application needs to restart again, false otherwise.
|
||||
*/
|
||||
_updateExtensionsManifest: function(needsRestart) {
|
||||
_updateExtensionsManifest: function() {
|
||||
// When an operation is performed that requires a component re-registration
|
||||
// (extension enabled/disabled, installed, uninstalled), we must write the
|
||||
// set of paths where extensions live so that the startup system can determine
|
||||
|
@ -4004,9 +4079,6 @@ ExtensionManager.prototype = {
|
|||
|
||||
// Cache the enabled list for annotating the crash report subsequently
|
||||
gPref.setCharPref(PREF_EM_ENABLED_ITEMS, enabledItems.join(","));
|
||||
|
||||
// Now refresh the compatibility manifest.
|
||||
this._extensionListChanged = needsRestart;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -4765,8 +4837,7 @@ ExtensionManager.prototype = {
|
|||
availableUpdateHash : null,
|
||||
availableUpdateVersion: null,
|
||||
availableUpdateInfo : null };
|
||||
for (var p in props)
|
||||
ds.setItemProperty(id, EM_R(p), props[p]);
|
||||
ds.setItemProperties(id, props);
|
||||
ds.updateProperty(id, "availableUpdateURL");
|
||||
|
||||
this._setOp(id, OP_NEEDS_INSTALL);
|
||||
|
@ -4806,8 +4877,7 @@ ExtensionManager.prototype = {
|
|||
availableUpdateHash : null,
|
||||
availableUpdateVersion : null,
|
||||
availableUpdateInfo : null };
|
||||
for (var p in props)
|
||||
ds.setItemProperty(id, EM_R(p), props[p]);
|
||||
ds.setItemProperties(id, props);
|
||||
ds.updateProperty(id, "availableUpdateURL");
|
||||
|
||||
this._setOp(id, OP_NEEDS_UPGRADE);
|
||||
|
@ -5670,10 +5740,12 @@ ExtensionManager.prototype = {
|
|||
// being updated during an install.
|
||||
if (!manager) {
|
||||
var id = currItem.id
|
||||
ds.setItemProperty(id, EM_R("availableUpdateURL"), null);
|
||||
ds.setItemProperty(id, EM_R("availableUpdateHash"), null);
|
||||
ds.setItemProperty(id, EM_R("availableUpdateVersion"), null);
|
||||
ds.setItemProperty(id, EM_R("availableUpdateInfo"), null);
|
||||
ds.setItemProperties(id, {
|
||||
availableUpdateURL: null,
|
||||
availableUpdateHash: null,
|
||||
availableUpdateVersion: null,
|
||||
availableUpdateInfo: null
|
||||
});
|
||||
ds.updateProperty(id, "availableUpdateURL");
|
||||
ds.updateProperty(id, "updateable");
|
||||
}
|
||||
|
@ -7547,6 +7619,20 @@ ExtensionsDataSource.prototype = {
|
|||
this.Flush();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets one or more properties for an item.
|
||||
* @param id
|
||||
* The ID of the item
|
||||
* @param properties
|
||||
* A JS object which maps properties to values.
|
||||
*/
|
||||
setItemProperties: function (id, properties) {
|
||||
var item = getResourceForID(id);
|
||||
for (var key in properties)
|
||||
this._setProperty(this._inner, item, EM_R(key), properties[key]);
|
||||
this.Flush();
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts the RDF resource for an item into a container.
|
||||
* @param id
|
||||
|
@ -8143,9 +8229,11 @@ ExtensionsDataSource.prototype = {
|
|||
hash = EM_L(addon.xpiHash);
|
||||
version = EM_L(addon.version);
|
||||
}
|
||||
this.setItemProperty(addon.id, EM_R("availableUpdateURL"), url);
|
||||
this.setItemProperty(addon.id, EM_R("availableUpdateHash"), hash);
|
||||
this.setItemProperty(addon.id, EM_R("availableUpdateVersion"), version);
|
||||
this.setItemProperties(addon.id, {
|
||||
availableUpdateURL: url,
|
||||
availableUpdateHash: hash,
|
||||
availableUpdateVersion: version
|
||||
});
|
||||
this.updateProperty(addon.id, "availableUpdateURL");
|
||||
},
|
||||
|
||||
|
@ -8710,6 +8798,12 @@ ExtensionsDataSource.prototype = {
|
|||
},
|
||||
|
||||
Flush: function() {
|
||||
// For some operations we block repeated flushing until all operations
|
||||
// are complete to reduce file accesses that can trigger bug 431065
|
||||
if (!gAllowFlush) {
|
||||
gDSNeedsFlush = true;
|
||||
return;
|
||||
}
|
||||
if (this._inner instanceof Ci.nsIRDFRemoteDataSource)
|
||||
this._inner.Flush();
|
||||
},
|
||||
|
|
Загрузка…
Ссылка в новой задаче