Bug 1893164 - Make CancelImport() won't cancel a request if the URI is been waiting by other requests. r=jonco

In the following module graph:

0.html
  +---- 1.mjs
    +---- non_existing.mjs
    +---- 3.mjs
  +----- 2.mjs
    +---- 3.mjs

Both 1.mjs and 2.mjs have a common submodule called 3.mjs
But 1.mjs also has a non-existing submodule, so we can't instantiate the
module graph of 1.mjs. which in turn will cancel 3.mjs

But 3.mjs is also a sub-module of 2.mjs, so in order to instantiate the
module graph of 2.mjs, we skip canceling 3.mjs when we processed 1.mjs

Differential Revision: https://phabricator.services.mozilla.com/D209210
This commit is contained in:
Yoshi Cheng-Hao Huang 2024-05-07 16:03:20 +00:00
parent 085d7d33ce
commit 803c459eb4
8 changed files with 53 additions and 2 deletions

View file

@ -0,0 +1,3 @@
/* eslint-disable import/no-named-default, import/no-unresolved */
import { default as default_non } from "./non_existing.mjs";
import { default as default_3 } from "./bug_1893164_module_3.mjs";

View file

@ -0,0 +1,5 @@
/* eslint-disable import/no-named-default */
import { default as default_3 } from "./bug_1893164_module_3.mjs";
module2_loaded = true;
result = default_3;

View file

@ -0,0 +1 @@
export default 3;

View file

@ -3,6 +3,9 @@ support-files = [
"bug_1865410_module_a.mjs",
"bug_1865410_module_b.mjs",
"bug_1873417.mjs",
"bug_1893164_module_1.mjs",
"bug_1893164_module_2.mjs",
"bug_1893164_module_3.mjs",
"classic_script.js",
"module_chain_1.mjs",
"module_chain_2.mjs",
@ -34,6 +37,8 @@ support-files = [
["test_bug_1873417.html"]
["test_bug_1893164.html"]
["test_importMap_with_external_script.html"]
["test_importMap_with_nonexisting_module.html"]
["test_dynamic_importMap_with_external_script.html"]

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test module cancel</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script>
var module2_loaded = false, result;
SimpleTest.waitForExplicitFinish();
function testLoaded() {
ok(module2_loaded, 'module_2.mjs should be loaded');
ok(result == 3, "result should be 3 from module_3.mjs");
SimpleTest.finish();
}
</script>
<script src="./bug_1893164_module_1.mjs" type="module"></script>
<script src="./bug_1893164_module_2.mjs" type="module"></script>
<body onload='testLoaded()'></body>

View file

@ -108,8 +108,6 @@ void ModuleLoadRequest::SetReady() {
// dependencies have had their source loaded, parsed as a module and the
// modules instantiated.
AssertAllImportsFinished();
ScriptLoadRequest::SetReady();
if (mWaitingParentRequest) {
@ -195,6 +193,7 @@ void ModuleLoadRequest::DependenciesLoaded() {
MOZ_ASSERT(!IsErrored());
CheckModuleDependenciesLoaded();
AssertAllImportsFinished();
SetReady();
LoadFinished();
}
@ -224,6 +223,11 @@ void ModuleLoadRequest::CheckModuleDependenciesLoaded() {
void ModuleLoadRequest::CancelImports() {
for (size_t i = 0; i < mImports.Length(); i++) {
if (mLoader->IsFetchingAndHasWaitingRequest(mImports[i])) {
LOG(("CancelImports import %p is fetching and has waiting\n",
mImports[i].get()));
continue;
}
mImports[i]->Cancel();
}
}

View file

@ -1494,6 +1494,17 @@ void ModuleLoaderBase::MoveModulesTo(ModuleLoaderBase* aDest) {
mFetchedModules.Clear();
}
bool ModuleLoaderBase::IsFetchingAndHasWaitingRequest(
ModuleLoadRequest* aRequest) {
auto entry = mFetchingModules.Lookup(aRequest->mURI);
if (!entry) {
return false;
}
RefPtr<LoadingRequest> loadingRequest = entry.Data();
return !loadingRequest->mWaiting.IsEmpty();
}
#undef LOG
#undef LOG_ENABLED

View file

@ -480,6 +480,8 @@ class ModuleLoaderBase : public nsISupports {
nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
bool IsFetchingAndHasWaitingRequest(ModuleLoadRequest* aRequest);
// The slot stored in ImportMetaResolve function.
enum { ModulePrivateSlot = 0, SlotCount };