Bug 1540668 - IDB: Add a timer for ShutdownWorkThreads; r=asuth, dr=chutten

Differential Revision: https://phabricator.services.mozilla.com/D25745
This commit is contained in:
Jan Varga 2019-04-02 13:16:55 +02:00
parent 7f35fd333c
commit 0269846741
2 changed files with 70 additions and 0 deletions

View File

@ -74,6 +74,7 @@
#include "nsCOMPtr.h"
#include "nsDataHashtable.h"
#include "nsEscape.h"
#include "nsExceptionHandler.h"
#include "nsHashKeys.h"
#include "nsNetUtil.h"
#include "nsIAsyncInputStream.h"
@ -273,6 +274,20 @@ const char kPrefFileHandleEnabled[] = "dom.fileHandle.enabled";
const uint32_t kDeleteTimeoutMs = 1000;
/**
* Automatically crash the browser if IndexedDB shutdown takes this long. We've
* chosen a value that is longer than the value for QuotaManager shutdown timer
* which is currently set to 30 seconds. We've also chosen a value that is long
* long enough that it is unlikely for the problem to be falsely triggered by
* slow system I/O. We've also chosen a value long enough so that automated
* tests should time out and fail if IndexedDB shutdown hangs. Also, this value
* is long enough so that testers can notice the IndexedDB shutdown hang; we
* want to know about the hangs, not hide them. On the other hand this value is
* less than 60 seconds which is used by nsTerminator to crash a hung main
* process.
*/
#define SHUTDOWN_TIMEOUT_MS 50000
#ifdef DEBUG
const int32_t kDEBUGThreadPriority = nsISupportsPriority::PRIORITY_NORMAL;
@ -7850,6 +7865,8 @@ class QuotaClient final : public mozilla::dom::quota::Client {
private:
~QuotaClient() override;
void ShutdownTimedOut();
static void DeleteTimerCallback(nsITimer* aTimer, void* aClosure);
nsresult GetDirectory(PersistenceType aPersistenceType,
@ -16209,6 +16226,17 @@ void QuotaClient::ShutdownWorkThreads() {
AbortOperations(VoidCString());
nsCOMPtr<nsITimer> timer = NS_NewTimer();
MOZ_ALWAYS_SUCCEEDS(timer->InitWithNamedFuncCallback(
[](nsITimer* aTimer, void* aClosure) {
auto quotaClient = static_cast<QuotaClient*>(aClosure);
quotaClient->ShutdownTimedOut();
},
this, SHUTDOWN_TIMEOUT_MS, nsITimer::TYPE_ONE_SHOT,
"indexeddb::QuotaClient::ShutdownWorkThreads::SpinEventLoopTimer"));
// This should release any IDB related quota objects or directory locks.
MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() {
return (!gFactoryOps || gFactoryOps->IsEmpty()) &&
@ -16216,6 +16244,8 @@ void QuotaClient::ShutdownWorkThreads() {
!mCurrentMaintenance;
}));
MOZ_ALWAYS_SUCCEEDS(timer->Cancel());
// And finally, shutdown all threads.
RefPtr<ConnectionPool> connectionPool = gConnectionPool.get();
if (connectionPool) {
@ -16243,6 +16273,37 @@ void QuotaClient::ShutdownWorkThreads() {
}
}
void QuotaClient::ShutdownTimedOut() {
AssertIsOnBackgroundThread();
MOZ_DIAGNOSTIC_ASSERT(
(gFactoryOps && !gFactoryOps->IsEmpty()) ||
(gLiveDatabaseHashtable && gLiveDatabaseHashtable->Count()) ||
mCurrentMaintenance);
nsCString data;
if (gFactoryOps && !gFactoryOps->IsEmpty()) {
data.Append("gFactoryOps: ");
data.AppendInt(static_cast<uint32_t>(gFactoryOps->Length()));
data.Append("\n");
}
if (gLiveDatabaseHashtable && gLiveDatabaseHashtable->Count()) {
data.Append("gLiveDatabaseHashtable: ");
data.AppendInt(gLiveDatabaseHashtable->Count());
data.Append("\n");
}
if (mCurrentMaintenance) {
data.Append("mCurrentMaintenance\n");
}
CrashReporter::AnnotateCrashReport(
CrashReporter::Annotation::IndexedDBShutdownTimeout, data);
MOZ_CRASH("IndexedDB shutdown timed out");
}
void QuotaClient::DeleteTimerCallback(nsITimer* aTimer, void* aClosure) {
AssertIsOnBackgroundThread();
MOZ_ASSERT(aTimer);

View File

@ -364,6 +364,15 @@ IAccessibleConfig:
the computer's registry. The value is always set to "NoSystemTypeLibOrPS"
type: string
IndexedDBShutdownTimeout:
description: >
This annotation is present if IndexedDB shutdown was not finished in time
and the browser was crashed instead of waiting for IndexedDB shutdown to
finish. The condition that caused the hang is contained in the annotation.
type: string
content: false
ping: true
InstallTime:
description: >
The time when Firefox was installed expressed as seconds since the Epoch