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);
|
MutexAutoLock lock(mUnprocessedMutex);
|
||||||
|
|
||||||
Unused << mUnprocessedModuleLoads.emplaceBack(std::move(aModLoadInfo));
|
mUnprocessedModuleLoads.insertBack(
|
||||||
|
new UnprocessedModuleLoadInfoContainer(std::move(aModLoadInfo)));
|
||||||
|
|
||||||
ScheduleNonEmptyQueueProcessing(lock);
|
ScheduleNonEmptyQueueProcessing(lock);
|
||||||
}
|
}
|
||||||
|
|
@ -327,7 +328,8 @@ void UntrustedModulesProcessor::Enqueue(ModuleLoadInfoVec&& aEvents) {
|
||||||
MutexAutoLock lock(mUnprocessedMutex);
|
MutexAutoLock lock(mUnprocessedMutex);
|
||||||
|
|
||||||
for (auto& event : aEvents) {
|
for (auto& event : aEvents) {
|
||||||
Unused << mUnprocessedModuleLoads.emplaceBack(std::move(event));
|
mUnprocessedModuleLoads.insertBack(
|
||||||
|
new UnprocessedModuleLoadInfoContainer(std::move(event)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduleNonEmptyQueueProcessing(lock);
|
ScheduleNonEmptyQueueProcessing(lock);
|
||||||
|
|
@ -580,33 +582,14 @@ void UntrustedModulesProcessor::BackgroundProcessModuleLoadQueueChildProcess() {
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||||
}
|
}
|
||||||
|
|
||||||
UntrustedModulesProcessor::LoadsVec
|
UnprocessedModuleLoads UntrustedModulesProcessor::ExtractLoadingEventsToProcess(
|
||||||
UntrustedModulesProcessor::ExtractLoadingEventsToProcess(size_t aMaxLength) {
|
size_t aMaxLength) {
|
||||||
LoadsVec loadsToProcess;
|
UnprocessedModuleLoads loadsToProcess;
|
||||||
|
|
||||||
MutexAutoLock lock(mUnprocessedMutex);
|
MutexAutoLock lock(mUnprocessedMutex);
|
||||||
CancelScheduledProcessing(lock);
|
CancelScheduledProcessing(lock);
|
||||||
|
|
||||||
// The potential size of mProcessedModuleLoads if all of the unprocessed
|
loadsToProcess.splice(0, mUnprocessedModuleLoads, 0, aMaxLength);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return loadsToProcess;
|
return loadsToProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -620,9 +603,9 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadsVec loadsToProcess =
|
UnprocessedModuleLoads loadsToProcess =
|
||||||
ExtractLoadingEventsToProcess(UntrustedModulesData::kMaxEvents);
|
ExtractLoadingEventsToProcess(UntrustedModulesData::kMaxEvents);
|
||||||
if (!IsReadyForBackgroundProcessing() || loadsToProcess.empty()) {
|
if (!IsReadyForBackgroundProcessing() || loadsToProcess.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -639,7 +622,9 @@ void UntrustedModulesProcessor::ProcessModuleLoadQueue() {
|
||||||
uint32_t sanitizationFailures = 0;
|
uint32_t sanitizationFailures = 0;
|
||||||
uint32_t trustTestFailures = 0;
|
uint32_t trustTestFailures = 0;
|
||||||
|
|
||||||
for (glue::EnhancedModuleLoadInfo& entry : loadsToProcess) {
|
for (UnprocessedModuleLoadInfoContainer* container : loadsToProcess) {
|
||||||
|
glue::EnhancedModuleLoadInfo& entry = container->mInfo;
|
||||||
|
|
||||||
if (!IsReadyForBackgroundProcessing()) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -779,9 +764,9 @@ UntrustedModulesProcessor::ProcessModuleLoadQueueChildProcess(
|
||||||
AssertRunningOnLazyIdleThread();
|
AssertRunningOnLazyIdleThread();
|
||||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||||
|
|
||||||
LoadsVec loadsToProcess =
|
UnprocessedModuleLoads loadsToProcess =
|
||||||
ExtractLoadingEventsToProcess(UntrustedModulesData::kMaxEvents);
|
ExtractLoadingEventsToProcess(UntrustedModulesData::kMaxEvents);
|
||||||
if (loadsToProcess.empty()) {
|
if (loadsToProcess.isEmpty()) {
|
||||||
// Nothing to process
|
// Nothing to process
|
||||||
return GetModulesTrustPromise::CreateAndResolve(Nothing(), __func__);
|
return GetModulesTrustPromise::CreateAndResolve(Nothing(), __func__);
|
||||||
}
|
}
|
||||||
|
|
@ -794,7 +779,9 @@ UntrustedModulesProcessor::ProcessModuleLoadQueueChildProcess(
|
||||||
nsTHashtable<nsStringCaseInsensitiveHashKey> moduleNtPathSet;
|
nsTHashtable<nsStringCaseInsensitiveHashKey> moduleNtPathSet;
|
||||||
|
|
||||||
// Build a set of modules to be processed by the parent
|
// 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()) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return GetModulesTrustPromise::CreateAndReject(
|
return GetModulesTrustPromise::CreateAndReject(
|
||||||
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
|
||||||
|
|
@ -875,7 +862,7 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
||||||
ModulesMap& modules = aModulesAndLoads.mModMapResult.ref().mModules;
|
ModulesMap& modules = aModulesAndLoads.mModMapResult.ref().mModules;
|
||||||
const uint32_t& trustTestFailures =
|
const uint32_t& trustTestFailures =
|
||||||
aModulesAndLoads.mModMapResult.ref().mTrustTestFailures;
|
aModulesAndLoads.mModMapResult.ref().mTrustTestFailures;
|
||||||
LoadsVec& loads = aModulesAndLoads.mLoads;
|
UnprocessedModuleLoads& loads = aModulesAndLoads.mLoads;
|
||||||
|
|
||||||
if (modules.IsEmpty() && !trustTestFailures) {
|
if (modules.IsEmpty() && !trustTestFailures) {
|
||||||
// No data, nothing to save.
|
// No data, nothing to save.
|
||||||
|
|
@ -894,7 +881,8 @@ void UntrustedModulesProcessor::CompleteProcessing(
|
||||||
uint32_t sanitizationFailures = 0;
|
uint32_t sanitizationFailures = 0;
|
||||||
|
|
||||||
if (!modules.IsEmpty()) {
|
if (!modules.IsEmpty()) {
|
||||||
for (auto&& item : loads) {
|
for (UnprocessedModuleLoadInfoContainer* container : loads) {
|
||||||
|
glue::EnhancedModuleLoadInfo& item = container->mInfo;
|
||||||
if (!IsReadyForBackgroundProcessing()) {
|
if (!IsReadyForBackgroundProcessing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,22 @@ using ModulesTrustPromise = MozPromise<ModulesMapResult, nsresult, true>;
|
||||||
using GetModulesTrustIpcPromise =
|
using GetModulesTrustIpcPromise =
|
||||||
MozPromise<Maybe<ModulesMapResult>, ipc::ResponseRejectReason, true>;
|
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 {
|
class UntrustedModulesProcessor final : public nsIObserver {
|
||||||
public:
|
public:
|
||||||
static RefPtr<UntrustedModulesProcessor> Create(
|
static RefPtr<UntrustedModulesProcessor> Create(
|
||||||
|
|
@ -84,20 +100,18 @@ class UntrustedModulesProcessor final : public nsIObserver {
|
||||||
void BackgroundProcessModuleLoadQueue();
|
void BackgroundProcessModuleLoadQueue();
|
||||||
void ProcessModuleLoadQueue();
|
void ProcessModuleLoadQueue();
|
||||||
|
|
||||||
using LoadsVec = Vector<glue::EnhancedModuleLoadInfo>;
|
|
||||||
|
|
||||||
// Extract the loading events from mUnprocessedModuleLoads to process and
|
// Extract the loading events from mUnprocessedModuleLoads to process and
|
||||||
// move to mProcessedModuleLoads. It's guaranteed that the total length of
|
// move to mProcessedModuleLoads. It's guaranteed that the total length of
|
||||||
// mProcessedModuleLoads will not exceed |aMaxLength|.
|
// mProcessedModuleLoads will not exceed |aMaxLength|.
|
||||||
LoadsVec ExtractLoadingEventsToProcess(size_t aMaxLength);
|
UnprocessedModuleLoads ExtractLoadingEventsToProcess(size_t aMaxLength);
|
||||||
|
|
||||||
class ModulesMapResultWithLoads final {
|
class ModulesMapResultWithLoads final {
|
||||||
public:
|
public:
|
||||||
ModulesMapResultWithLoads(Maybe<ModulesMapResult>&& aModMapResult,
|
ModulesMapResultWithLoads(Maybe<ModulesMapResult>&& aModMapResult,
|
||||||
LoadsVec&& aLoads)
|
UnprocessedModuleLoads&& aLoads)
|
||||||
: mModMapResult(std::move(aModMapResult)), mLoads(std::move(aLoads)) {}
|
: mModMapResult(std::move(aModMapResult)), mLoads(std::move(aLoads)) {}
|
||||||
Maybe<ModulesMapResult> mModMapResult;
|
Maybe<ModulesMapResult> mModMapResult;
|
||||||
LoadsVec mLoads;
|
UnprocessedModuleLoads mLoads;
|
||||||
};
|
};
|
||||||
|
|
||||||
using GetModulesTrustPromise =
|
using GetModulesTrustPromise =
|
||||||
|
|
@ -140,7 +154,7 @@ class UntrustedModulesProcessor final : public nsIObserver {
|
||||||
Mutex mModuleCacheMutex;
|
Mutex mModuleCacheMutex;
|
||||||
|
|
||||||
// The members in this group are protected by mUnprocessedMutex
|
// The members in this group are protected by mUnprocessedMutex
|
||||||
Vector<glue::EnhancedModuleLoadInfo> mUnprocessedModuleLoads;
|
UnprocessedModuleLoads mUnprocessedModuleLoads;
|
||||||
nsCOMPtr<nsIRunnable> mIdleRunnable;
|
nsCOMPtr<nsIRunnable> mIdleRunnable;
|
||||||
|
|
||||||
// This member must only be touched on mThread
|
// This member must only be touched on mThread
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue