forked from mirrors/gecko-dev
Bug 1750790 - Use a linked list to hold unprocessed loading events. r=mhowell
Bug 1750791 changed the data strucutre of processed loading events to a linked list. This patch does the same for unprocessed loading events. Differential Revision: https://phabricator.services.mozilla.com/D140584
This commit is contained in:
parent
42e4421792
commit
05cc5ccd6d
2 changed files with 41 additions and 39 deletions
|
|
@ -311,7 +311,8 @@ void UntrustedModulesProcessor::Enqueue(
|
|||
|
||||
MutexAutoLock lock(mUnprocessedMutex);
|
||||
|
||||
Unused << mUnprocessedModuleLoads.emplaceBack(std::move(aModLoadInfo));
|
||||
mUnprocessedModuleLoads.insertBack(
|
||||
new UnprocessedModuleLoadInfoContainer(std::move(aModLoadInfo)));
|
||||
|
||||
ScheduleNonEmptyQueueProcessing(lock);
|
||||
}
|
||||
|
|
@ -327,7 +328,8 @@ void UntrustedModulesProcessor::Enqueue(ModuleLoadInfoVec&& aEvents) {
|
|||
MutexAutoLock lock(mUnprocessedMutex);
|
||||
|
||||
for (auto& event : aEvents) {
|
||||
Unused << mUnprocessedModuleLoads.emplaceBack(std::move(event));
|
||||
mUnprocessedModuleLoads.insertBack(
|
||||
new UnprocessedModuleLoadInfoContainer(std::move(event)));
|
||||
}
|
||||
|
||||
ScheduleNonEmptyQueueProcessing(lock);
|
||||
|
|
@ -580,33 +582,14 @@ void UntrustedModulesProcessor::BackgroundProcessModuleLoadQueueChildProcess() {
|
|||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
UntrustedModulesProcessor::LoadsVec
|
||||
UntrustedModulesProcessor::ExtractLoadingEventsToProcess(size_t aMaxLength) {
|
||||
LoadsVec loadsToProcess;
|
||||
UnprocessedModuleLoads UntrustedModulesProcessor::ExtractLoadingEventsToProcess(
|
||||
size_t aMaxLength) {
|
||||
UnprocessedModuleLoads loadsToProcess;
|
||||
|
||||
MutexAutoLock lock(mUnprocessedMutex);
|
||||
CancelScheduledProcessing(lock);
|
||||
|
||||
// The potential size of mProcessedModuleLoads if all of the unprocessed
|
||||
// events are from third-party modules.
|
||||
const size_t newDataLength =
|
||||
mProcessedModuleLoads.mNumEvents + mUnprocessedModuleLoads.length();
|
||||
if (newDataLength <= aMaxLength) {
|
||||
loadsToProcess.swap(mUnprocessedModuleLoads);
|
||||
} else {
|
||||
// To prevent mProcessedModuleLoads from exceeding |aMaxLength|,
|
||||
// we process the first items in the mUnprocessedModuleLoads,
|
||||
// leaving the the remaining events for the next time.
|
||||
const size_t capacity =
|
||||
aMaxLength > mProcessedModuleLoads.mNumEvents
|
||||
? (aMaxLength - mProcessedModuleLoads.mNumEvents)
|
||||
: 0;
|
||||
auto moveRangeBegin = mUnprocessedModuleLoads.begin();
|
||||
auto moveRangeEnd = moveRangeBegin + capacity;
|
||||
Unused << loadsToProcess.moveAppend(moveRangeBegin, moveRangeEnd);
|
||||
mUnprocessedModuleLoads.erase(moveRangeBegin, moveRangeEnd);
|
||||
}
|
||||
|
||||
loadsToProcess.splice(0, mUnprocessedModuleLoads, 0, aMaxLength);
|
||||
return loadsToProcess;
|
||||
}
|
||||
|
||||
|
|
@ -620,9 +603,9 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
|||
return;
|
||||
}
|
||||
|
||||
LoadsVec loadsToProcess =
|
||||
UnprocessedModuleLoads loadsToProcess =
|
||||
ExtractLoadingEventsToProcess(UntrustedModulesData::kMaxEvents);
|
||||
if (!IsReadyForBackgroundProcessing() || loadsToProcess.empty()) {
|
||||
if (!IsReadyForBackgroundProcessing() || loadsToProcess.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -639,7 +622,9 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
|||
uint32_t sanitizationFailures = 0;
|
||||
uint32_t trustTestFailures = 0;
|
||||
|
||||
for (glue::EnhancedModuleLoadInfo& entry : loadsToProcess) {
|
||||
for (UnprocessedModuleLoadInfoContainer* container : loadsToProcess) {
|
||||
glue::EnhancedModuleLoadInfo& entry = container->mInfo;
|
||||
|
||||
if (!IsReadyForBackgroundProcessing()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -779,9 +764,9 @@ UntrustedModulesProcessor::ProcessModuleLoadQueueChildProcess(
|
|||
AssertRunningOnLazyIdleThread();
|
||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||
|
||||
LoadsVec loadsToProcess =
|
||||
UnprocessedModuleLoads loadsToProcess =
|
||||
ExtractLoadingEventsToProcess(UntrustedModulesData::kMaxEvents);
|
||||
if (loadsToProcess.empty()) {
|
||||
if (loadsToProcess.isEmpty()) {
|
||||
// Nothing to process
|
||||
return GetModulesTrustPromise::CreateAndResolve(Nothing(), __func__);
|
||||
}
|
||||
|
|
@ -794,7 +779,9 @@ UntrustedModulesProcessor::ProcessModuleLoadQueueChildProcess(
|
|||
nsTHashtable<nsStringCaseInsensitiveHashKey> moduleNtPathSet;
|
||||
|
||||
// Build a set of modules to be processed by the parent
|
||||
for (glue::EnhancedModuleLoadInfo& entry : loadsToProcess) {
|
||||
for (UnprocessedModuleLoadInfoContainer* container : loadsToProcess) {
|
||||
glue::EnhancedModuleLoadInfo& entry = container->mInfo;
|
||||
|
||||
if (!IsReadyForBackgroundProcessing()) {
|
||||
return GetModulesTrustPromise::CreateAndReject(
|
||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||
|
|
@ -875,7 +862,7 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
|||
ModulesMap& modules = aModulesAndLoads.mModMapResult.ref().mModules;
|
||||
const uint32_t& trustTestFailures =
|
||||
aModulesAndLoads.mModMapResult.ref().mTrustTestFailures;
|
||||
LoadsVec& loads = aModulesAndLoads.mLoads;
|
||||
UnprocessedModuleLoads& loads = aModulesAndLoads.mLoads;
|
||||
|
||||
if (modules.IsEmpty() && !trustTestFailures) {
|
||||
// No data, nothing to save.
|
||||
|
|
@ -894,7 +881,8 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
|||
uint32_t sanitizationFailures = 0;
|
||||
|
||||
if (!modules.IsEmpty()) {
|
||||
for (auto&& item : loads) {
|
||||
for (UnprocessedModuleLoadInfoContainer* container : loads) {
|
||||
glue::EnhancedModuleLoadInfo& item = container->mInfo;
|
||||
if (!IsReadyForBackgroundProcessing()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,22 @@ using ModulesTrustPromise = MozPromise<ModulesMapResult, nsresult, true>;
|
|||
using GetModulesTrustIpcPromise =
|
||||
MozPromise<Maybe<ModulesMapResult>, ipc::ResponseRejectReason, true>;
|
||||
|
||||
struct UnprocessedModuleLoadInfoContainer final
|
||||
: public LinkedListElement<UnprocessedModuleLoadInfoContainer> {
|
||||
glue::EnhancedModuleLoadInfo mInfo;
|
||||
|
||||
template <typename T>
|
||||
explicit UnprocessedModuleLoadInfoContainer(T&& aInfo)
|
||||
: mInfo(std::move(aInfo)) {}
|
||||
|
||||
UnprocessedModuleLoadInfoContainer(
|
||||
const UnprocessedModuleLoadInfoContainer&) = delete;
|
||||
UnprocessedModuleLoadInfoContainer& operator=(
|
||||
const UnprocessedModuleLoadInfoContainer&) = delete;
|
||||
};
|
||||
using UnprocessedModuleLoads =
|
||||
AutoCleanLinkedList<UnprocessedModuleLoadInfoContainer>;
|
||||
|
||||
class UntrustedModulesProcessor final : public nsIObserver {
|
||||
public:
|
||||
static RefPtr<UntrustedModulesProcessor> Create(
|
||||
|
|
@ -84,20 +100,18 @@ class UntrustedModulesProcessor final : public nsIObserver {
|
|||
void BackgroundProcessModuleLoadQueue();
|
||||
void ProcessModuleLoadQueue();
|
||||
|
||||
using LoadsVec = Vector<glue::EnhancedModuleLoadInfo>;
|
||||
|
||||
// Extract the loading events from mUnprocessedModuleLoads to process and
|
||||
// move to mProcessedModuleLoads. It's guaranteed that the total length of
|
||||
// mProcessedModuleLoads will not exceed |aMaxLength|.
|
||||
LoadsVec ExtractLoadingEventsToProcess(size_t aMaxLength);
|
||||
UnprocessedModuleLoads ExtractLoadingEventsToProcess(size_t aMaxLength);
|
||||
|
||||
class ModulesMapResultWithLoads final {
|
||||
public:
|
||||
ModulesMapResultWithLoads(Maybe<ModulesMapResult>&& aModMapResult,
|
||||
LoadsVec&& aLoads)
|
||||
UnprocessedModuleLoads&& aLoads)
|
||||
: mModMapResult(std::move(aModMapResult)), mLoads(std::move(aLoads)) {}
|
||||
Maybe<ModulesMapResult> mModMapResult;
|
||||
LoadsVec mLoads;
|
||||
UnprocessedModuleLoads mLoads;
|
||||
};
|
||||
|
||||
using GetModulesTrustPromise =
|
||||
|
|
@ -140,7 +154,7 @@ class UntrustedModulesProcessor final : public nsIObserver {
|
|||
Mutex mModuleCacheMutex;
|
||||
|
||||
// The members in this group are protected by mUnprocessedMutex
|
||||
Vector<glue::EnhancedModuleLoadInfo> mUnprocessedModuleLoads;
|
||||
UnprocessedModuleLoads mUnprocessedModuleLoads;
|
||||
nsCOMPtr<nsIRunnable> mIdleRunnable;
|
||||
|
||||
// This member must only be touched on mThread
|
||||
|
|
|
|||
Loading…
Reference in a new issue