mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-28 18:17:29 +09:00
Fix a rare crash with asm.js caching.
This commit is contained in:
parent
2029eff3f1
commit
03fe589f41
2 changed files with 316 additions and 116 deletions
|
|
@ -69,6 +69,8 @@ namespace asmjscache {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
class ParentRunnable;
|
||||||
|
|
||||||
// Anything smaller should compile fast enough that caching will just add
|
// Anything smaller should compile fast enough that caching will just add
|
||||||
// overhead.
|
// overhead.
|
||||||
static const size_t sMinCachedModuleLength = 10000;
|
static const size_t sMinCachedModuleLength = 10000;
|
||||||
|
|
@ -76,6 +78,10 @@ static const size_t sMinCachedModuleLength = 10000;
|
||||||
// The number of characters to hash into the Metadata::Entry::mFastHash.
|
// The number of characters to hash into the Metadata::Entry::mFastHash.
|
||||||
static const unsigned sNumFastHashChars = 4096;
|
static const unsigned sNumFastHashChars = 4096;
|
||||||
|
|
||||||
|
// Track all live parent actors.
|
||||||
|
typedef nsTArray<const ParentRunnable*> ParentActorArray;
|
||||||
|
StaticAutoPtr<ParentActorArray> sLiveParentActors;
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
WriteMetadataFile(nsIFile* aMetadataFile, const Metadata& aMetadata)
|
WriteMetadataFile(nsIFile* aMetadataFile, const Metadata& aMetadata)
|
||||||
{
|
{
|
||||||
|
|
@ -236,6 +242,94 @@ EvictEntries(nsIFile* aDirectory, const nsACString& aGroup,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Client
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
class Client
|
||||||
|
: public quota::Client
|
||||||
|
{
|
||||||
|
static Client* sInstance;
|
||||||
|
|
||||||
|
bool mShutdownRequested;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Client();
|
||||||
|
|
||||||
|
static bool
|
||||||
|
IsShuttingDownOnBackgroundThread()
|
||||||
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
|
if (sInstance) {
|
||||||
|
return sInstance->IsShuttingDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QuotaManager::IsShuttingDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
IsShuttingDownOnNonBackgroundThread()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!IsOnBackgroundThread());
|
||||||
|
|
||||||
|
return QuotaManager::IsShuttingDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsShuttingDown() const
|
||||||
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
|
return mShutdownRequested;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_INLINE_DECL_REFCOUNTING(Client, override)
|
||||||
|
|
||||||
|
virtual Type
|
||||||
|
GetType() override;
|
||||||
|
|
||||||
|
virtual nsresult
|
||||||
|
InitOrigin(PersistenceType aPersistenceType,
|
||||||
|
const nsACString& aGroup,
|
||||||
|
const nsACString& aOrigin,
|
||||||
|
const AtomicBool& aCanceled,
|
||||||
|
UsageInfo* aUsageInfo) override;
|
||||||
|
|
||||||
|
virtual nsresult
|
||||||
|
GetUsageForOrigin(PersistenceType aPersistenceType,
|
||||||
|
const nsACString& aGroup,
|
||||||
|
const nsACString& aOrigin,
|
||||||
|
const AtomicBool& aCanceled,
|
||||||
|
UsageInfo* aUsageInfo) override;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
OnOriginClearCompleted(PersistenceType aPersistenceType,
|
||||||
|
const nsACString& aOrigin)
|
||||||
|
override;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
ReleaseIOThreadObjects() override;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
AbortOperations(const nsACString& aOrigin) override;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
AbortOperationsForProcess(ContentParentId aContentParentId) override;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
StartIdleMaintenance() override;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
StopIdleMaintenance() override;
|
||||||
|
|
||||||
|
virtual void
|
||||||
|
ShutdownWorkThreads() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
~Client();
|
||||||
|
};
|
||||||
|
|
||||||
// FileDescriptorHolder owns a file descriptor and its memory mapping.
|
// FileDescriptorHolder owns a file descriptor and its memory mapping.
|
||||||
// FileDescriptorHolder is derived by two runnable classes (that is,
|
// FileDescriptorHolder is derived by two runnable classes (that is,
|
||||||
// (Parent|Child)Runnable.
|
// (Parent|Child)Runnable.
|
||||||
|
|
@ -897,6 +991,13 @@ ParentRunnable::FinishOnOwningThread()
|
||||||
FileDescriptorHolder::Finish();
|
FileDescriptorHolder::Finish();
|
||||||
|
|
||||||
mDirectoryLock = nullptr;
|
mDirectoryLock = nullptr;
|
||||||
|
|
||||||
|
MOZ_ASSERT(sLiveParentActors);
|
||||||
|
sLiveParentActors->RemoveElement(this);
|
||||||
|
|
||||||
|
if (sLiveParentActors->IsEmpty()) {
|
||||||
|
sLiveParentActors = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
@ -1140,6 +1241,10 @@ AllocEntryParent(OpenMode aOpenMode,
|
||||||
{
|
{
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
|
if (NS_WARN_IF(Client::IsShuttingDownOnBackgroundThread())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(aPrincipalInfo.type() == PrincipalInfo::TNullPrincipalInfo)) {
|
if (NS_WARN_IF(aPrincipalInfo.type() == PrincipalInfo::TNullPrincipalInfo)) {
|
||||||
MOZ_ASSERT(false);
|
MOZ_ASSERT(false);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -1148,6 +1253,12 @@ AllocEntryParent(OpenMode aOpenMode,
|
||||||
RefPtr<ParentRunnable> runnable =
|
RefPtr<ParentRunnable> runnable =
|
||||||
new ParentRunnable(aPrincipalInfo, aOpenMode, aWriteParams);
|
new ParentRunnable(aPrincipalInfo, aOpenMode, aWriteParams);
|
||||||
|
|
||||||
|
if (!sLiveParentActors) {
|
||||||
|
sLiveParentActors = new ParentActorArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
sLiveParentActors->AppendElement(runnable);
|
||||||
|
|
||||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||||
|
|
||||||
|
|
@ -1712,128 +1823,163 @@ CloseEntryForWrite(size_t aSize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Client : public quota::Client
|
/*******************************************************************************
|
||||||
|
* Client
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
Client* Client::sInstance = nullptr;
|
||||||
|
|
||||||
|
Client::Client()
|
||||||
|
: mShutdownRequested(false)
|
||||||
{
|
{
|
||||||
~Client() {}
|
AssertIsOnBackgroundThread();
|
||||||
|
MOZ_ASSERT(!sInstance, "We expect this to be a singleton!");
|
||||||
|
|
||||||
public:
|
sInstance = this;
|
||||||
NS_IMETHOD_(MozExternalRefCountType)
|
}
|
||||||
AddRef() override;
|
|
||||||
|
|
||||||
NS_IMETHOD_(MozExternalRefCountType)
|
Client::~Client()
|
||||||
Release() override;
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
MOZ_ASSERT(sInstance == this, "We expect this to be a singleton!");
|
||||||
|
|
||||||
virtual Type
|
sInstance = nullptr;
|
||||||
GetType() override
|
}
|
||||||
{
|
|
||||||
return ASMJS;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual nsresult
|
Client::Type
|
||||||
InitOrigin(PersistenceType aPersistenceType,
|
Client::GetType()
|
||||||
const nsACString& aGroup,
|
{
|
||||||
const nsACString& aOrigin,
|
return ASMJS;
|
||||||
const AtomicBool& aCanceled,
|
}
|
||||||
UsageInfo* aUsageInfo) override
|
|
||||||
{
|
|
||||||
if (!aUsageInfo) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
return GetUsageForOrigin(aPersistenceType,
|
|
||||||
aGroup,
|
|
||||||
aOrigin,
|
|
||||||
aCanceled,
|
|
||||||
aUsageInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual nsresult
|
|
||||||
GetUsageForOrigin(PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin,
|
|
||||||
const AtomicBool& aCanceled,
|
|
||||||
UsageInfo* aUsageInfo) override
|
|
||||||
{
|
|
||||||
QuotaManager* qm = QuotaManager::Get();
|
|
||||||
MOZ_ASSERT(qm, "We were being called by the QuotaManager");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> directory;
|
|
||||||
nsresult rv = qm->GetDirectoryForOrigin(aPersistenceType, aOrigin,
|
|
||||||
getter_AddRefs(directory));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
MOZ_ASSERT(directory, "We're here because the origin directory exists");
|
|
||||||
|
|
||||||
rv = directory->Append(NS_LITERAL_STRING(ASMJSCACHE_DIRECTORY_NAME));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
DebugOnly<bool> exists;
|
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(directory->Exists(&exists)) && exists);
|
|
||||||
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
|
||||||
rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
bool hasMore;
|
|
||||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
|
|
||||||
hasMore && !aCanceled) {
|
|
||||||
nsCOMPtr<nsISupports> entry;
|
|
||||||
rv = entries->GetNext(getter_AddRefs(entry));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
|
|
||||||
NS_ENSURE_TRUE(file, NS_NOINTERFACE);
|
|
||||||
|
|
||||||
int64_t fileSize;
|
|
||||||
rv = file->GetFileSize(&fileSize);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
MOZ_ASSERT(fileSize >= 0, "Negative size?!");
|
|
||||||
|
|
||||||
// Since the client is not explicitly storing files, append to database
|
|
||||||
// usage which represents implicit storage allocation.
|
|
||||||
aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize));
|
|
||||||
}
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Client::InitOrigin(PersistenceType aPersistenceType,
|
||||||
|
const nsACString& aGroup,
|
||||||
|
const nsACString& aOrigin,
|
||||||
|
const AtomicBool& aCanceled,
|
||||||
|
UsageInfo* aUsageInfo)
|
||||||
|
{
|
||||||
|
if (!aUsageInfo) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
return GetUsageForOrigin(aPersistenceType,
|
||||||
|
aGroup,
|
||||||
|
aOrigin,
|
||||||
|
aCanceled,
|
||||||
|
aUsageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void
|
nsresult
|
||||||
OnOriginClearCompleted(PersistenceType aPersistenceType,
|
Client::GetUsageForOrigin(PersistenceType aPersistenceType,
|
||||||
const nsACString& aOrigin)
|
const nsACString& aGroup,
|
||||||
override
|
const nsACString& aOrigin,
|
||||||
{ }
|
const AtomicBool& aCanceled,
|
||||||
|
UsageInfo* aUsageInfo)
|
||||||
|
{
|
||||||
|
QuotaManager* qm = QuotaManager::Get();
|
||||||
|
MOZ_ASSERT(qm, "We were being called by the QuotaManager");
|
||||||
|
|
||||||
virtual void
|
nsCOMPtr<nsIFile> directory;
|
||||||
ReleaseIOThreadObjects() override
|
nsresult rv = qm->GetDirectoryForOrigin(aPersistenceType, aOrigin,
|
||||||
{ }
|
getter_AddRefs(directory));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void
|
MOZ_ASSERT(directory, "We're here because the origin directory exists");
|
||||||
AbortOperations(const nsACString& aOrigin) override
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual void
|
rv = directory->Append(NS_LITERAL_STRING(ASMJSCACHE_DIRECTORY_NAME));
|
||||||
AbortOperationsForProcess(ContentParentId aContentParentId) override
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
{ }
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void
|
DebugOnly<bool> exists;
|
||||||
StartIdleMaintenance() override
|
MOZ_ASSERT(NS_SUCCEEDED(directory->Exists(&exists)) && exists);
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual void
|
nsCOMPtr<nsISimpleEnumerator> entries;
|
||||||
StopIdleMaintenance() override
|
rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
|
||||||
{ }
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void
|
bool hasMore;
|
||||||
ShutdownWorkThreads() override
|
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
|
||||||
{ }
|
hasMore && !aCanceled) {
|
||||||
|
nsCOMPtr<nsISupports> entry;
|
||||||
|
rv = entries->GetNext(getter_AddRefs(entry));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
|
||||||
nsAutoRefCnt mRefCnt;
|
if (NS_WARN_IF(!file)) {
|
||||||
NS_DECL_OWNINGTHREAD
|
return NS_NOINTERFACE;
|
||||||
};
|
}
|
||||||
|
|
||||||
NS_IMPL_ADDREF(asmjscache::Client)
|
int64_t fileSize;
|
||||||
NS_IMPL_RELEASE(asmjscache::Client)
|
rv = file->GetFileSize(&fileSize);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(fileSize >= 0, "Negative size?!");
|
||||||
|
|
||||||
|
// Since the client is not explicitly storing files, append to database
|
||||||
|
// usage which represents implicit storage allocation.
|
||||||
|
aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize));
|
||||||
|
}
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Client::OnOriginClearCompleted(PersistenceType aPersistenceType,
|
||||||
|
const nsACString& aOrigin)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Client::ReleaseIOThreadObjects()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Client::AbortOperations(const nsACString& aOrigin)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Client::AbortOperationsForProcess(ContentParentId aContentParentId)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Client::StartIdleMaintenance()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Client::StopIdleMaintenance()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Client::ShutdownWorkThreads()
|
||||||
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
|
if (sLiveParentActors) {
|
||||||
|
nsIThread* currentThread = NS_GetCurrentThread();
|
||||||
|
MOZ_ASSERT(currentThread);
|
||||||
|
|
||||||
|
do {
|
||||||
|
MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread));
|
||||||
|
} while (!sLiveParentActors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
quota::Client*
|
quota::Client*
|
||||||
CreateClient()
|
CreateClient()
|
||||||
|
|
|
||||||
|
|
@ -18185,11 +18185,25 @@ QuotaClient::ShutdownWorkThreads()
|
||||||
|
|
||||||
mShutdownRequested = true;
|
mShutdownRequested = true;
|
||||||
|
|
||||||
|
// Shutdown maintenance thread pool (this spins the event loop until all
|
||||||
|
// threads are gone). This should release any maintenance related quota
|
||||||
|
// objects.
|
||||||
if (mMaintenanceThreadPool) {
|
if (mMaintenanceThreadPool) {
|
||||||
mMaintenanceThreadPool->Shutdown();
|
mMaintenanceThreadPool->Shutdown();
|
||||||
mMaintenanceThreadPool = nullptr;
|
mMaintenanceThreadPool = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Let any runnables dispatched from dying maintenance threads to be
|
||||||
|
// processed. This should release any maintenance related directory locks.
|
||||||
|
if (mCurrentMaintenance) {
|
||||||
|
nsIThread* currentThread = NS_GetCurrentThread();
|
||||||
|
MOZ_ASSERT(currentThread);
|
||||||
|
|
||||||
|
do {
|
||||||
|
MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread));
|
||||||
|
} while (!mCurrentMaintenance);
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<ConnectionPool> connectionPool = gConnectionPool.get();
|
RefPtr<ConnectionPool> connectionPool = gConnectionPool.get();
|
||||||
if (connectionPool) {
|
if (connectionPool) {
|
||||||
connectionPool->Shutdown();
|
connectionPool->Shutdown();
|
||||||
|
|
@ -18409,7 +18423,8 @@ Maintenance::Start()
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(mState == State::Initial);
|
MOZ_ASSERT(mState == State::Initial);
|
||||||
|
|
||||||
if (IsAborted()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
|
||||||
|
IsAborted()) {
|
||||||
return NS_ERROR_ABORT;
|
return NS_ERROR_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -18433,7 +18448,8 @@ Maintenance::CreateIndexedDatabaseManager()
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(mState == State::CreateIndexedDatabaseManager);
|
MOZ_ASSERT(mState == State::CreateIndexedDatabaseManager);
|
||||||
|
|
||||||
if (IsAborted()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
|
||||||
|
IsAborted()) {
|
||||||
return NS_ERROR_ABORT;
|
return NS_ERROR_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -18458,7 +18474,8 @@ Maintenance::OpenDirectory()
|
||||||
MOZ_ASSERT(!mDirectoryLock);
|
MOZ_ASSERT(!mDirectoryLock);
|
||||||
MOZ_ASSERT(QuotaManager::Get());
|
MOZ_ASSERT(QuotaManager::Get());
|
||||||
|
|
||||||
if (IsAborted()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
|
||||||
|
IsAborted()) {
|
||||||
return NS_ERROR_ABORT;
|
return NS_ERROR_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -18482,7 +18499,8 @@ Maintenance::DirectoryOpen()
|
||||||
MOZ_ASSERT(mState == State::DirectoryOpenPending);
|
MOZ_ASSERT(mState == State::DirectoryOpenPending);
|
||||||
MOZ_ASSERT(mDirectoryLock);
|
MOZ_ASSERT(mDirectoryLock);
|
||||||
|
|
||||||
if (IsAborted()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
|
||||||
|
IsAborted()) {
|
||||||
return NS_ERROR_ABORT;
|
return NS_ERROR_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -18512,7 +18530,8 @@ Maintenance::DirectoryWork()
|
||||||
// We have to find all database files that match any persistence type and any
|
// We have to find all database files that match any persistence type and any
|
||||||
// origin. We ignore anything out of the ordinary for now.
|
// origin. We ignore anything out of the ordinary for now.
|
||||||
|
|
||||||
if (IsAborted()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
|
||||||
|
IsAborted()) {
|
||||||
return NS_ERROR_ABORT;
|
return NS_ERROR_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -18699,8 +18718,10 @@ Maintenance::DirectoryWork()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsCString suffix;
|
||||||
nsCString group;
|
nsCString group;
|
||||||
nsCString origin;
|
nsCString origin;
|
||||||
|
bool isApp;
|
||||||
nsTArray<nsString> databasePaths;
|
nsTArray<nsString> databasePaths;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
@ -18756,19 +18777,18 @@ Maintenance::DirectoryWork()
|
||||||
|
|
||||||
// Found a database.
|
// Found a database.
|
||||||
if (databasePaths.IsEmpty()) {
|
if (databasePaths.IsEmpty()) {
|
||||||
|
MOZ_ASSERT(suffix.IsEmpty());
|
||||||
MOZ_ASSERT(group.IsEmpty());
|
MOZ_ASSERT(group.IsEmpty());
|
||||||
MOZ_ASSERT(origin.IsEmpty());
|
MOZ_ASSERT(origin.IsEmpty());
|
||||||
|
|
||||||
int64_t dummyTimeStamp;
|
int64_t dummyTimeStamp;
|
||||||
nsCString dummySuffix;
|
|
||||||
bool dummyIsApp;
|
|
||||||
if (NS_WARN_IF(NS_FAILED(
|
if (NS_WARN_IF(NS_FAILED(
|
||||||
quotaManager->GetDirectoryMetadata2(originDir,
|
quotaManager->GetDirectoryMetadata2(originDir,
|
||||||
&dummyTimeStamp,
|
&dummyTimeStamp,
|
||||||
dummySuffix,
|
suffix,
|
||||||
group,
|
group,
|
||||||
origin,
|
origin,
|
||||||
&dummyIsApp)))) {
|
&isApp)))) {
|
||||||
// Not much we can do here...
|
// Not much we can do here...
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -18784,6 +18804,22 @@ Maintenance::DirectoryWork()
|
||||||
group,
|
group,
|
||||||
origin,
|
origin,
|
||||||
Move(databasePaths)));
|
Move(databasePaths)));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> directory;
|
||||||
|
|
||||||
|
// Idle maintenance may occur before origin is initailized.
|
||||||
|
// Ensure origin is initialized first. It will initialize all origins
|
||||||
|
// for temporary storage including IDB origins.
|
||||||
|
rv = quotaManager->EnsureOriginIsInitialized(persistenceType,
|
||||||
|
suffix,
|
||||||
|
group,
|
||||||
|
origin,
|
||||||
|
isApp,
|
||||||
|
getter_AddRefs(directory));
|
||||||
|
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -18835,6 +18871,11 @@ Maintenance::BeginDatabaseMaintenance()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
|
||||||
|
IsAborted()) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<nsThreadPool> threadPool;
|
RefPtr<nsThreadPool> threadPool;
|
||||||
|
|
||||||
for (DirectoryInfo& directoryInfo : mDirectoryInfos) {
|
for (DirectoryInfo& directoryInfo : mDirectoryInfos) {
|
||||||
|
|
@ -19021,6 +19062,11 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
|
||||||
|
mMaintenance->IsAborted()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> databaseFile = GetFileForPath(mDatabasePath);
|
nsCOMPtr<nsIFile> databaseFile = GetFileForPath(mDatabasePath);
|
||||||
MOZ_ASSERT(databaseFile);
|
MOZ_ASSERT(databaseFile);
|
||||||
|
|
||||||
|
|
@ -19037,10 +19083,6 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase()
|
||||||
|
|
||||||
AutoClose autoClose(connection);
|
AutoClose autoClose(connection);
|
||||||
|
|
||||||
if (mMaintenance->IsAborted()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoProgressHandler progressHandler(mMaintenance);
|
AutoProgressHandler progressHandler(mMaintenance);
|
||||||
if (NS_WARN_IF(NS_FAILED(progressHandler.Register(connection)))) {
|
if (NS_WARN_IF(NS_FAILED(progressHandler.Register(connection)))) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -19059,20 +19101,12 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMaintenance->IsAborted()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MaintenanceAction maintenanceAction;
|
MaintenanceAction maintenanceAction;
|
||||||
rv = DetermineMaintenanceAction(connection, databaseFile, &maintenanceAction);
|
rv = DetermineMaintenanceAction(connection, databaseFile, &maintenanceAction);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMaintenance->IsAborted()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (maintenanceAction) {
|
switch (maintenanceAction) {
|
||||||
case MaintenanceAction::Nothing:
|
case MaintenanceAction::Nothing:
|
||||||
break;
|
break;
|
||||||
|
|
@ -19099,6 +19133,11 @@ DatabaseMaintenance::CheckIntegrity(mozIStorageConnection* aConnection,
|
||||||
MOZ_ASSERT(aConnection);
|
MOZ_ASSERT(aConnection);
|
||||||
MOZ_ASSERT(aOk);
|
MOZ_ASSERT(aOk);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
|
||||||
|
mMaintenance->IsAborted()) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
// First do a full integrity_check. Scope statements tightly here because
|
// First do a full integrity_check. Scope statements tightly here because
|
||||||
|
|
@ -19216,6 +19255,11 @@ DatabaseMaintenance::DetermineMaintenanceAction(
|
||||||
MOZ_ASSERT(aDatabaseFile);
|
MOZ_ASSERT(aDatabaseFile);
|
||||||
MOZ_ASSERT(aMaintenanceAction);
|
MOZ_ASSERT(aMaintenanceAction);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
|
||||||
|
mMaintenance->IsAborted()) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t schemaVersion;
|
int32_t schemaVersion;
|
||||||
nsresult rv = aConnection->GetSchemaVersion(&schemaVersion);
|
nsresult rv = aConnection->GetSchemaVersion(&schemaVersion);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
|
@ -19425,6 +19469,11 @@ DatabaseMaintenance::IncrementalVacuum(mozIStorageConnection* aConnection)
|
||||||
MOZ_ASSERT(!IsOnBackgroundThread());
|
MOZ_ASSERT(!IsOnBackgroundThread());
|
||||||
MOZ_ASSERT(aConnection);
|
MOZ_ASSERT(aConnection);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
|
||||||
|
mMaintenance->IsAborted()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
"PRAGMA incremental_vacuum;"
|
"PRAGMA incremental_vacuum;"
|
||||||
));
|
));
|
||||||
|
|
@ -19442,6 +19491,11 @@ DatabaseMaintenance::FullVacuum(mozIStorageConnection* aConnection,
|
||||||
MOZ_ASSERT(aConnection);
|
MOZ_ASSERT(aConnection);
|
||||||
MOZ_ASSERT(aDatabaseFile);
|
MOZ_ASSERT(aDatabaseFile);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
|
||||||
|
mMaintenance->IsAborted()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
"VACUUM;"
|
"VACUUM;"
|
||||||
));
|
));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue