Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/io.js

Issue 5731880649359360: Don't delay Firefox startup (Closed)
Patch Set: Fixed wrong callback parameters Created March 14, 2014, 6:08 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/filterStorage.js ('k') | lib/utils.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/io.js
===================================================================
--- a/lib/io.js
+++ b/lib/io.js
@@ -65,84 +65,133 @@ let IO = exports.IO =
* Reads strings from a file asynchronously, calls listener.process() with
* each line read and with a null parameter once the read operation is done.
* The callback will be called when the operation is done.
*/
readFromFile: function(/**nsIFile|nsIURI*/ file, /**Boolean*/ decode, /**Object*/ listener, /**Function*/ callback, /**String*/ timeLineID)
{
try
{
+ let processing = false;
let buffer = "";
+ let loadEvent = null;
+ let errorEvent = null;
let uri = file instanceof Ci.nsIFile ? Services.io.newFileURI(file) : file;
let request = new XMLHttpRequest();
request.mozBackgroundRequest = true;
request.open("GET", uri.spec);
request.responseType = "moz-chunked-text";
request.overrideMimeType("text/plain" + (decode ? "? charset=utf-8" : ""));
- request.addEventListener("progress", function(event)
+ let onProgress = function(event)
{
if (timeLineID)
{
TimeLine.asyncStart(timeLineID);
}
let data = event.target.response;
- let index = Math.max(data.lastIndexOf("\n"), data.lastIndexOf("\r"));
+ let index = (processing ? -1 : Math.max(data.lastIndexOf("\n"), data.lastIndexOf("\r")));
if (index >= 0)
{
- let oldBuffer = buffer;
- buffer = data.substr(index + 1);
- data = data.substr(0, index + 1);
- let lines = data.split(/[\r\n]+/);
- lines.pop();
- lines[0] = oldBuffer + lines[0];
- for (let i = 0; i < lines.length; i++)
- listener.process(lines[i]);
+ // Protect against reentrance in case the listener processes events.
+ processing = true;
+ try
+ {
+ let oldBuffer = buffer;
+ buffer = data.substr(index + 1);
+ data = data.substr(0, index + 1);
+ let lines = data.split(/[\r\n]+/);
+ lines.pop();
+ lines[0] = oldBuffer + lines[0];
+ for (let i = 0; i < lines.length; i++)
+ listener.process(lines[i]);
+ }
+ finally
+ {
+ processing = false;
+ let e = {
+ target: {response: buffer}
+ };
+ buffer = "";
+ onProgress(e);
+
+ if (loadEvent)
+ {
+ let event = loadEvent;
+ loadEvent = null;
+ onLoad(event);
+ }
+
+ if (errorEvent)
+ {
+ let event = errorEvent;
+ errorEvent = null;
+ onError(event);
+ }
+ }
}
else
buffer += data;
if (timeLineID)
{
TimeLine.asyncEnd(timeLineID);
}
- }, false);
+ };
- request.addEventListener("load", function(event)
+ let onLoad = function(event)
{
+ if (processing)
+ {
+ // Still processing data, delay processing this event.
+ loadEvent = event;
+ return;
+ }
+
if (timeLineID)
{
TimeLine.asyncStart(timeLineID);
}
if (buffer !== "")
listener.process(buffer);
listener.process(null);
if (timeLineID)
{
TimeLine.asyncEnd(timeLineID);
TimeLine.asyncDone(timeLineID);
}
callback(null);
- }, false);
+ };
- request.addEventListener("error", function()
+ let onError = function(event)
{
+ if (processing)
+ {
+ // Still processing data, delay processing this event.
+ errorEvent = event;
+ return;
+ }
+
let e = Cc["@mozilla.org/js/xpc/Exception;1"].createInstance(Ci.nsIXPCException);
e.initialize("File read operation failed", result, null, Components.stack, file, null);
callback(e);
if (timeLineID)
{
TimeLine.asyncDone(timeLineID);
}
- }, false);
+ };
+
+ request.addEventListener("progress", onProgress, false);
+ request.addEventListener("load", onLoad, false);
+ request.addEventListener("error", onError, false);
request.send(null);
}
catch (e)
{
callback(e);
}
},
« no previous file with comments | « lib/filterStorage.js ('k') | lib/utils.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld