diff --git a/src/js/assets.js b/src/js/assets.js index b7b947337..733871842 100644 --- a/src/js/assets.js +++ b/src/js/assets.js @@ -307,6 +307,14 @@ var updateLocalChecksums = function() { var getRepoMetadata = function(callback) { callback = callback || nullFunc; + // https://github.com/gorhill/uBlock/issues/515 + // Handle re-entrancy here, i.e. we MUST NOT tamper with the waiting list + // of callers, if any, except to add one at the end of the list. + if ( repoMetadata !== null && repoMetadata.waiting.length !== 0 ) { + repoMetadata.waiting.push(callback); + return; + } + if ( exports.allowRemoteFetch && lastRepoMetaIsRemote === false ) { lastRepoMetaTimestamp = 0; } @@ -314,11 +322,7 @@ var getRepoMetadata = function(callback) { repoMetadata = null; } if ( repoMetadata !== null ) { - if ( repoMetadata.waiting.length !== 0 ) { - repoMetadata.waiting.push(callback); - } else { - callback(repoMetadata); - } + callback(repoMetadata); return; } @@ -356,9 +360,16 @@ var getRepoMetadata = function(callback) { updateLocalChecksums(); } // Notify all waiting callers - while ( callback = repoMetadata.waiting.pop() ) { - callback(repoMetadata); + // https://github.com/gorhill/uBlock/issues/515 + // VERY IMPORTANT: because of re-entrancy, we MUST: + // - process the waiting callers in a FIFO manner + // - not cache repoMetadata.waiting.length, we MUST use the live + // value, because it can change while looping + // - not change the waiting list until they are all processed + for ( var i = 0; i < repoMetadata.waiting.length; i++ ) { + repoMetadata.waiting[i](repoMetadata); } + repoMetadata.waiting.length = 0; }; var validateChecksums = function(details) { diff --git a/src/js/mirrors.js b/src/js/mirrors.js index 46bc6f617..9428b846e 100644 --- a/src/js/mirrors.js +++ b/src/js/mirrors.js @@ -497,7 +497,7 @@ var load = function() { var loadContent = function(urlKey, hash) { var binKey = storageKeyFromHash(hash); var onContentReady = function(bin) { - if ( vAPI.lastError || bin.hasOwnProperty(binKey) === false ) { + if ( vAPI.lastError() || bin.hasOwnProperty(binKey) === false ) { //console.debug('mirrors.load(): failed to load content "%s"', binKey); removeMetadata(urlKey); removeContent(binKey); diff --git a/src/js/storage.js b/src/js/storage.js index 75c2de39d..dcca33ddc 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -418,6 +418,7 @@ // https://github.com/gorhill/httpswitchboard/issues/15 // Ensure localhost et al. don't end up in the ubiquitous blacklist. + // TODO: do this only if it's not an [Adblock] list line = line .replace(/\s+#.*$/, '') .toLowerCase() @@ -594,10 +595,18 @@ var µb = this; var fromSelfie = false; + // Filter lists + // Whitelist + var countdown = 2; + // Final initialization steps after all needed assets are in memory. // - Initialize internal state with maybe already existing tabs. // - Schedule next update operation. - var onAllDone = function() { + var doCountdown = function() { + countdown -= 1; + if ( countdown !== 0 ) { + return; + } // https://github.com/gorhill/uBlock/issues/426 // Important: remove barrier to remote fetching, this was useful only // for launch time. @@ -610,16 +619,10 @@ µb.updater.restart(µb.firstUpdateAfter); }; - var filtersReady = false; - var whitelistReady = false; - // Filters are in memory. // Filter engines need PSL to be ready. var onFiltersReady = function() { - filtersReady = true; - if ( whitelistReady ) { - onAllDone(); - } + doCountdown(); }; // https://github.com/gorhill/uBlock/issues/226 @@ -627,10 +630,7 @@ // Whitelist parser needs PSL to be ready. // gorhill 2014-12-15: not anymore var onWhitelistReady = function() { - whitelistReady = true; - if ( filtersReady ) { - onAllDone(); - } + doCountdown(); }; // Load order because dependencies: