Bug 1842798 - Part 1: Remove use of MozPromise to wait for module fetch r=smaug
This replaces the promise with a list of module requests that are waiting for a resource to be fetched. When the fetch completes the waiting requests are resumed appropriately. This now happens immediately rather tha via dispatching a runnable. Differential Revision: https://phabricator.services.mozilla.com/D183272
This commit is contained in:
@@ -50,6 +50,19 @@ mozilla::LazyLogModule ModuleLoaderBase::gModuleLoaderBaseLog(
|
||||
#define LOG_ENABLED() \
|
||||
MOZ_LOG_TEST(ModuleLoaderBase::gModuleLoaderBaseLog, mozilla::LogLevel::Debug)
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// ModuleLoaderBase::WaitingRequests
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ModuleLoaderBase::WaitingRequests)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(ModuleLoaderBase::WaitingRequests, mWaiting)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ModuleLoaderBase::WaitingRequests)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ModuleLoaderBase::WaitingRequests)
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// ModuleLoaderBase
|
||||
//////////////////////////////////////////////////////////////
|
||||
@@ -58,7 +71,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ModuleLoaderBase)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(ModuleLoaderBase, mFetchedModules,
|
||||
NS_IMPL_CYCLE_COLLECTION(ModuleLoaderBase, mFetchingModules, mFetchedModules,
|
||||
mDynamicImportRequests, mGlobalObject, mEventTarget,
|
||||
mLoader)
|
||||
|
||||
@@ -408,10 +421,7 @@ nsresult ModuleLoaderBase::StartOrRestartModuleLoad(ModuleLoadRequest* aRequest,
|
||||
|
||||
if (aRestart == RestartRequest::No && ModuleMapContainsURL(request->mURI)) {
|
||||
LOG(("ScriptLoadRequest (%p): Waiting for module fetch", aRequest));
|
||||
WaitForModuleFetch(request->mURI)
|
||||
->Then(mEventTarget, __func__, request,
|
||||
&ModuleLoadRequest::ModuleLoaded,
|
||||
&ModuleLoadRequest::LoadFailed);
|
||||
WaitForModuleFetch(request);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -471,17 +481,15 @@ void ModuleLoaderBase::SetModuleFetchStarted(ModuleLoadRequest* aRequest) {
|
||||
MOZ_ASSERT(aRequest->IsFetching());
|
||||
MOZ_ASSERT(!ModuleMapContainsURL(aRequest->mURI));
|
||||
|
||||
mFetchingModules.InsertOrUpdate(
|
||||
aRequest->mURI, RefPtr<mozilla::GenericNonExclusivePromise::Private>{});
|
||||
mFetchingModules.InsertOrUpdate(aRequest->mURI, nullptr);
|
||||
}
|
||||
|
||||
void ModuleLoaderBase::SetModuleFetchFinishedAndResumeWaitingRequests(
|
||||
ModuleLoadRequest* aRequest, nsresult aResult) {
|
||||
// Update module map with the result of fetching a single module script.
|
||||
//
|
||||
// If any requests for the same URL are waiting on this one to complete, they
|
||||
// will have ModuleLoaded or LoadFailed on them when the promise is
|
||||
// resolved/rejected. This is set up in StartLoad.
|
||||
// If any requests for the same URL are waiting on this one to complete, call
|
||||
// ModuleLoaded or LoadFailed to resume or fail them as appropriate.
|
||||
|
||||
MOZ_ASSERT(aRequest->mLoader == this);
|
||||
|
||||
@@ -490,8 +498,9 @@ void ModuleLoaderBase::SetModuleFetchFinishedAndResumeWaitingRequests(
|
||||
"%u)",
|
||||
aRequest, aRequest->mModuleScript.get(), unsigned(aResult)));
|
||||
|
||||
RefPtr<mozilla::GenericNonExclusivePromise::Private> promise;
|
||||
if (!mFetchingModules.Remove(aRequest->mURI, getter_AddRefs(promise))) {
|
||||
RefPtr<WaitingRequests> waitingRequests;
|
||||
if (!mFetchingModules.Remove(aRequest->mURI,
|
||||
getter_AddRefs(waitingRequests))) {
|
||||
LOG(
|
||||
("ScriptLoadRequest (%p): Key not found in mFetchingModules, "
|
||||
"assuming we have an inline module or have finished fetching already",
|
||||
@@ -504,37 +513,47 @@ void ModuleLoaderBase::SetModuleFetchFinishedAndResumeWaitingRequests(
|
||||
|
||||
mFetchedModules.InsertOrUpdate(aRequest->mURI, RefPtr{moduleScript});
|
||||
|
||||
if (promise) {
|
||||
if (moduleScript) {
|
||||
LOG(("ScriptLoadRequest (%p): resolving %p", aRequest, promise.get()));
|
||||
promise->Resolve(true, __func__);
|
||||
} else {
|
||||
LOG(("ScriptLoadRequest (%p): rejecting %p", aRequest, promise.get()));
|
||||
promise->Reject(aResult, __func__);
|
||||
}
|
||||
if (waitingRequests) {
|
||||
LOG(("ScriptLoadRequest (%p): Resuming waiting requests", aRequest));
|
||||
ResumeWaitingRequests(waitingRequests, bool(moduleScript));
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<mozilla::GenericNonExclusivePromise>
|
||||
ModuleLoaderBase::WaitForModuleFetch(nsIURI* aURL) {
|
||||
MOZ_ASSERT(ModuleMapContainsURL(aURL));
|
||||
void ModuleLoaderBase::ResumeWaitingRequests(WaitingRequests* aWaitingRequests,
|
||||
bool aSuccess) {
|
||||
for (ModuleLoadRequest* request : aWaitingRequests->mWaiting) {
|
||||
ResumeWaitingRequest(request, aSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
nsURIHashKey key(aURL);
|
||||
if (auto entry = mFetchingModules.Lookup(aURL)) {
|
||||
if (!entry.Data()) {
|
||||
entry.Data() = new mozilla::GenericNonExclusivePromise::Private(__func__);
|
||||
void ModuleLoaderBase::ResumeWaitingRequest(ModuleLoadRequest* aRequest,
|
||||
bool aSuccess) {
|
||||
if (aSuccess) {
|
||||
aRequest->ModuleLoaded();
|
||||
} else {
|
||||
aRequest->LoadFailed();
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleLoaderBase::WaitForModuleFetch(ModuleLoadRequest* aRequest) {
|
||||
nsIURI* uri = aRequest->mURI;
|
||||
MOZ_ASSERT(ModuleMapContainsURL(uri));
|
||||
|
||||
if (auto entry = mFetchingModules.Lookup(uri)) {
|
||||
RefPtr<WaitingRequests> waitingRequests = entry.Data();
|
||||
if (!waitingRequests) {
|
||||
waitingRequests = new WaitingRequests();
|
||||
mFetchingModules.InsertOrUpdate(uri, waitingRequests);
|
||||
}
|
||||
return entry.Data();
|
||||
|
||||
waitingRequests->mWaiting.AppendElement(aRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ModuleScript> ms;
|
||||
MOZ_ALWAYS_TRUE(mFetchedModules.Get(aURL, getter_AddRefs(ms)));
|
||||
if (!ms) {
|
||||
return mozilla::GenericNonExclusivePromise::CreateAndReject(
|
||||
NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
MOZ_ALWAYS_TRUE(mFetchedModules.Get(uri, getter_AddRefs(ms)));
|
||||
|
||||
return mozilla::GenericNonExclusivePromise::CreateAndResolve(true, __func__);
|
||||
ResumeWaitingRequest(aRequest, bool(ms));
|
||||
}
|
||||
|
||||
ModuleScript* ModuleLoaderBase::GetFetchedModule(nsIURI* aURL) const {
|
||||
@@ -1017,8 +1036,9 @@ void ModuleLoaderBase::Shutdown() {
|
||||
CancelAndClearDynamicImports();
|
||||
|
||||
for (const auto& entry : mFetchingModules) {
|
||||
if (entry.GetData()) {
|
||||
entry.GetData()->Reject(NS_ERROR_FAILURE, __func__);
|
||||
RefPtr<WaitingRequests> waitingRequests(entry.GetData());
|
||||
if (waitingRequests) {
|
||||
ResumeWaitingRequests(waitingRequests, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user