Bug 1368567 - Remove useless main-thread IO from XUL store; r=florian
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 02 Jun 2017 23:18:50 -0400
changeset 362129 c7f34448197790499d4709a6e5a36aa7aa876b1b
parent 362128 f8b1a6312c02403f84f3882230d30ab013a8eb80
child 362130 8def89fd63a0b2f819a73e2a4a0fad50a5331715
push id91015
push usereakhgari@mozilla.com
push dateSat, 03 Jun 2017 15:47:58 +0000
treeherdermozilla-inbound@c7f344481977 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian
bugs1368567
milestone55.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 1368567 - Remove useless main-thread IO from XUL store; r=florian
toolkit/components/xulstore/XULStore.js
toolkit/components/xulstore/tests/xpcshell/head.js
toolkit/components/xulstore/tests/xpcshell/test_XULStore.js
toolkit/components/xulstore/tests/xpcshell/test_XULStoreImportWithoutPreExistingLocalStoreRDF.js
toolkit/components/xulstore/tests/xpcshell/xpcshell.ini
--- a/toolkit/components/xulstore/XULStore.js
+++ b/toolkit/components/xulstore/XULStore.js
@@ -60,20 +60,21 @@ XULStore.prototype = {
   _writeTimer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer),
 
   load() {
     Services.obs.addObserver(this, "profile-before-change", true);
 
     this._storeFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
     this._storeFile.append(STOREDB_FILENAME);
 
-    if (!this._storeFile.exists()) {
+    try {
+      this.readFile();
+    } catch (e) {
+      // If readFile() throws, it means that the file didn't exist.
       this.import();
-    } else {
-      this.readFile();
     }
   },
 
   observe(subject, topic, data) {
     this.writeFile();
     if (topic == "profile-before-change") {
       this._saveAllowed = false;
     }
@@ -88,19 +89,16 @@ XULStore.prototype = {
     dump("XULStore: " + message + "\n");
     Services.console.logStringMessage("XULStore: " + message);
   },
 
   import() {
     let localStoreFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
 
     localStoreFile.append("localstore.rdf");
-    if (!localStoreFile.exists()) {
-      return;
-    }
 
     const RDF = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
     const persistKey = RDF.GetResource("http://home.netscape.com/NC-rdf#persist");
 
     this.log("Import localstore from " + localStoreFile.path);
 
     let localStoreURI = Services.io.newFileURI(localStoreFile).spec;
     let localStore = RDF.GetDataSourceBlocking(localStoreURI);
@@ -148,17 +146,19 @@ XULStore.prototype = {
     let stream = Cc["@mozilla.org/network/file-input-stream;1"].
                  createInstance(Ci.nsIFileInputStream);
     let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
     try {
       stream.init(this._storeFile, MODE_RDONLY, FILE_PERMS, 0);
       this._data = json.decodeFromStream(stream, stream.available());
     } catch (e) {
       this.log("Error reading JSON: " + e);
-      // Ignore problem, we'll just continue on with an empty dataset.
+      if (e.result == Cr.NS_ERROR_FILE_NOT_FOUND) {
+        throw e; // Let the caller handle it!
+      }
     } finally {
       stream.close();
     }
   },
 
   async writeFile() {
     if (!this._needsSaving)
       return;
new file mode 100644
--- /dev/null
+++ b/toolkit/components/xulstore/tests/xpcshell/head.js
@@ -0,0 +1,48 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/◦
+*/
+
+"use strict"
+
+function checkValue(uri, id, attr, reference) {
+  let value = XULStore.getValue(uri, id, attr);
+  do_check_eq(value, reference);
+}
+
+function checkValueExists(uri, id, attr, exists) {
+  do_check_eq(XULStore.hasValue(uri, id, attr), exists);
+}
+
+function getIDs(uri) {
+  let it = XULStore.getIDsEnumerator(uri);
+  let result = [];
+
+  while (it.hasMore()) {
+    let value = it.getNext();
+    result.push(value);
+  }
+
+  result.sort();
+  return result;
+}
+
+function getAttributes(uri, id) {
+  let it = XULStore.getAttributeEnumerator(uri, id);
+
+  let result = [];
+
+  while (it.hasMore()) {
+    let value = it.getNext();
+    result.push(value);
+  }
+
+  result.sort();
+  return result;
+}
+
+function checkArrays(a, b) {
+  a.sort();
+  b.sort();
+  do_check_true(a.toString() == b.toString());
+}
+
--- a/toolkit/components/xulstore/tests/xpcshell/test_XULStore.js
+++ b/toolkit/components/xulstore/tests/xpcshell/test_XULStore.js
@@ -15,58 +15,16 @@ var XULStore = null;
 var browserURI = "chrome://browser/content/browser.xul";
 var aboutURI = "about:config";
 
 function run_test() {
   do_get_profile();
   run_next_test();
 }
 
-function checkValue(uri, id, attr, reference) {
-  let value = XULStore.getValue(uri, id, attr);
-  do_check_true(value === reference);
-}
-
-function checkValueExists(uri, id, attr, exists) {
-  do_check_eq(XULStore.hasValue(uri, id, attr), exists);
-}
-
-function getIDs(uri) {
-  let it = XULStore.getIDsEnumerator(uri);
-  let result = [];
-
-  while (it.hasMore()) {
-    let value = it.getNext();
-    result.push(value);
-  }
-
-  result.sort();
-  return result;
-}
-
-function getAttributes(uri, id) {
-  let it = XULStore.getAttributeEnumerator(uri, id);
-
-  let result = [];
-
-  while (it.hasMore()) {
-    let value = it.getNext();
-    result.push(value);
-  }
-
-  result.sort();
-  return result;
-}
-
-function checkArrays(a, b) {
-  a.sort();
-  b.sort();
-  do_check_true(a.toString() == b.toString());
-}
-
 function checkOldStore() {
   checkArrays(["addon-bar", "main-window", "sidebar-title"], getIDs(browserURI));
   checkArrays(["collapsed"], getAttributes(browserURI, "addon-bar"));
   checkArrays(["height", "screenX", "screenY", "sizemode", "width"],
               getAttributes(browserURI, "main-window"));
   checkArrays(["value"], getAttributes(browserURI, "sidebar-title"));
 
   checkValue(browserURI, "addon-bar", "collapsed", "true");
new file mode 100644
--- /dev/null
+++ b/toolkit/components/xulstore/tests/xpcshell/test_XULStoreImportWithoutPreExistingLocalStoreRDF.js
@@ -0,0 +1,50 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/◦
+*/
+
+"use strict"
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+Cu.import("resource://gre/modules/osfile.jsm")
+
+var XULStore = null;
+var browserURI = "chrome://browser/content/browser.xul";
+var aboutURI = "about:config";
+
+function run_test() {
+  do_get_profile();
+  run_next_test();
+}
+
+function checkOldStore() {
+  checkArrays([], getIDs(browserURI));
+  checkArrays([], getAttributes(browserURI, "addon-bar"));
+  checkArrays([],
+              getAttributes(browserURI, "main-window"));
+  checkArrays([], getAttributes(browserURI, "sidebar-title"));
+
+  checkValue(browserURI, "addon-bar", "collapsed", "");
+  checkValue(browserURI, "main-window", "width", "");
+  checkValue(browserURI, "main-window", "height", "");
+  checkValue(browserURI, "main-window", "screenX", "");
+  checkValue(browserURI, "main-window", "screenY", "");
+  checkValue(browserURI, "main-window", "sizemode", "");
+  checkValue(browserURI, "sidebar-title", "value", "");
+
+  checkArrays([], getIDs(aboutURI));
+  checkArrays([], getAttributes(aboutURI, "lockCol"));
+  checkArrays([], getAttributes(aboutURI, "prefCol"));
+
+  checkValue(aboutURI, "prefCol", "ordinal", "");
+  checkValue(aboutURI, "prefCol", "sortDirection", "");
+  checkValue(aboutURI, "lockCol", "ordinal", "");
+}
+
+add_task(async function testImportWithoutPreExistingLocalStoreRDF() {
+  XULStore = Cc["@mozilla.org/xul/xulstore;1"].getService(Ci.nsIXULStore);
+  checkOldStore();
+});
--- a/toolkit/components/xulstore/tests/xpcshell/xpcshell.ini
+++ b/toolkit/components/xulstore/tests/xpcshell/xpcshell.ini
@@ -1,6 +1,8 @@
 [DEFAULT]
+head = head.js
 skip-if = toolkit == 'android'
 support-files =
   localstore.rdf
 
 [test_XULStore.js]
+[test_XULStoreImportWithoutPreExistingLocalStoreRDF.js]