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

Side by Side Diff: lib/io.js

Issue 5731880649359360: Don't delay Firefox startup (Closed)
Patch Set: Created March 13, 2014, 1:52 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/filterStorage.js ('k') | lib/utils.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 Eyeo GmbH 3 * Copyright (C) 2006-2014 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 63
64 /** 64 /**
65 * Reads strings from a file asynchronously, calls listener.process() with 65 * Reads strings from a file asynchronously, calls listener.process() with
66 * each line read and with a null parameter once the read operation is done. 66 * each line read and with a null parameter once the read operation is done.
67 * The callback will be called when the operation is done. 67 * The callback will be called when the operation is done.
68 */ 68 */
69 readFromFile: function(/**nsIFile|nsIURI*/ file, /**Boolean*/ decode, /**Objec t*/ listener, /**Function*/ callback, /**String*/ timeLineID) 69 readFromFile: function(/**nsIFile|nsIURI*/ file, /**Boolean*/ decode, /**Objec t*/ listener, /**Function*/ callback, /**String*/ timeLineID)
70 { 70 {
71 try 71 try
72 { 72 {
73 let processing = false;
73 let buffer = ""; 74 let buffer = "";
75 let loadEvent = null;
76 let errorEvent = null;
74 let uri = file instanceof Ci.nsIFile ? Services.io.newFileURI(file) : file ; 77 let uri = file instanceof Ci.nsIFile ? Services.io.newFileURI(file) : file ;
75 let request = new XMLHttpRequest(); 78 let request = new XMLHttpRequest();
76 request.mozBackgroundRequest = true; 79 request.mozBackgroundRequest = true;
77 request.open("GET", uri.spec); 80 request.open("GET", uri.spec);
78 request.responseType = "moz-chunked-text"; 81 request.responseType = "moz-chunked-text";
79 request.overrideMimeType("text/plain" + (decode ? "? charset=utf-8" : "")) ; 82 request.overrideMimeType("text/plain" + (decode ? "? charset=utf-8" : "")) ;
80 83
81 request.addEventListener("progress", function(event) 84 let onProgress = function(event)
82 { 85 {
83 if (timeLineID) 86 if (timeLineID)
84 { 87 {
85 TimeLine.asyncStart(timeLineID); 88 TimeLine.asyncStart(timeLineID);
86 } 89 }
87 90
88 let data = event.target.response; 91 let data = event.target.response;
89 let index = Math.max(data.lastIndexOf("\n"), data.lastIndexOf("\r")); 92 let index = (processing ? -1 : Math.max(data.lastIndexOf("\n"), data.las tIndexOf("\r")));
Felix Dahlke 2014/03/14 16:10:45 This doesn't really seem reentrant to me. What if
Wladimir Palant 2014/03/14 18:04:51 JavaScript is a single-threaded language, reentran
Felix Dahlke 2014/03/14 21:32:49 Ah, thought this was actually proper multithreadin
90 if (index >= 0) 93 if (index >= 0)
91 { 94 {
92 let oldBuffer = buffer; 95 // Protect against reentrance in case the listener processes events.
Felix Dahlke 2014/03/14 16:10:45 "processes multiple events" I suppose?
Wladimir Palant 2014/03/14 18:04:51 No, "processes events" = "spins the event loop"
93 buffer = data.substr(index + 1); 96 processing = true;
94 data = data.substr(0, index + 1); 97 try
95 let lines = data.split(/[\r\n]+/); 98 {
96 lines.pop(); 99 let oldBuffer = buffer;
97 lines[0] = oldBuffer + lines[0]; 100 buffer = data.substr(index + 1);
Felix Dahlke 2014/03/14 16:10:45 Is reference assignment atomic in Gecko? Otherwise
Wladimir Palant 2014/03/14 18:04:51 As I said, the only place where we might get reent
98 for (let i = 0; i < lines.length; i++) 101 data = data.substr(0, index + 1);
99 listener.process(lines[i]); 102 let lines = data.split(/[\r\n]+/);
103 lines.pop();
104 lines[0] = oldBuffer + lines[0];
105 for (let i = 0; i < lines.length; i++)
106 listener.process(lines[i]);
107 }
108 finally
109 {
110 processing = false;
111 let e = {
112 target: {response: buffer}
113 };
114 buffer = "";
115 onProgress(e);
116
117 if (loadEvent)
118 {
119 loadEvent = null;
120 onLoad(loadEvent);
Felix Dahlke 2014/03/14 16:10:45 onLoad(null) doesn't seem to be what's desired her
Wladimir Palant 2014/03/14 18:04:51 True, we need to save the original event before nu
121 }
122
123 if (errorEvent)
124 {
125 errorEvent = null;
126 onError(errorEvent);
127 }
128 }
100 } 129 }
101 else 130 else
102 buffer += data; 131 buffer += data;
103 132
104 if (timeLineID) 133 if (timeLineID)
105 { 134 {
106 TimeLine.asyncEnd(timeLineID); 135 TimeLine.asyncEnd(timeLineID);
107 } 136 }
108 }, false); 137 };
109 138
110 request.addEventListener("load", function(event) 139 let onLoad = function(event)
111 { 140 {
141 if (processing)
142 {
143 // Still processing data, delay processing this event.
144 loadEvent = event;
145 return;
146 }
147
112 if (timeLineID) 148 if (timeLineID)
113 { 149 {
114 TimeLine.asyncStart(timeLineID); 150 TimeLine.asyncStart(timeLineID);
115 } 151 }
116 152
117 if (buffer !== "") 153 if (buffer !== "")
118 listener.process(buffer); 154 listener.process(buffer);
119 listener.process(null); 155 listener.process(null);
120 156
121 if (timeLineID) 157 if (timeLineID)
122 { 158 {
123 TimeLine.asyncEnd(timeLineID); 159 TimeLine.asyncEnd(timeLineID);
124 TimeLine.asyncDone(timeLineID); 160 TimeLine.asyncDone(timeLineID);
125 } 161 }
126 162
127 callback(null); 163 callback(null);
128 }, false); 164 };
129 165
130 request.addEventListener("error", function() 166 let onError = function(event)
131 { 167 {
168 if (processing)
169 {
170 // Still processing data, delay processing this event.
171 errorEvent = event;
172 return;
173 }
174
132 let e = Cc["@mozilla.org/js/xpc/Exception;1"].createInstance(Ci.nsIXPCEx ception); 175 let e = Cc["@mozilla.org/js/xpc/Exception;1"].createInstance(Ci.nsIXPCEx ception);
133 e.initialize("File read operation failed", result, null, Components.stac k, file, null); 176 e.initialize("File read operation failed", result, null, Components.stac k, file, null);
134 callback(e); 177 callback(e);
135 178
136 if (timeLineID) 179 if (timeLineID)
137 { 180 {
138 TimeLine.asyncDone(timeLineID); 181 TimeLine.asyncDone(timeLineID);
139 } 182 }
140 }, false); 183 };
184
185 request.addEventListener("progress", onProgress, false);
186 request.addEventListener("load", onLoad, false);
187 request.addEventListener("error", onError, false);
141 188
142 request.send(null); 189 request.send(null);
143 } 190 }
144 catch (e) 191 catch (e)
145 { 192 {
146 callback(e); 193 callback(e);
147 } 194 }
148 }, 195 },
149 /** 196 /**
150 * Writes string data to a file asynchronously, optionally encodes it into 197 * Writes string data to a file asynchronously, optionally encodes it into
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 isFile: exists && file.isFile(), 377 isFile: exists && file.isFile(),
331 lastModified: exists ? file.lastModifiedTime : 0 378 lastModified: exists ? file.lastModifiedTime : 0
332 }); 379 });
333 } 380 }
334 catch(e) 381 catch(e)
335 { 382 {
336 callback(e); 383 callback(e);
337 } 384 }
338 } 385 }
339 } 386 }
OLDNEW
« 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