Bug 1151242 - Abort version change transactions more eagerly in the event of a crash, r=khuey.

This commit is contained in:
Ben Turner 2015-04-14 16:40:51 -07:00
Родитель 87eb48be41
Коммит bbcf9289d8
1 изменённых файлов: 57 добавлений и 31 удалений

Просмотреть файл

@ -6591,6 +6591,11 @@ class OpenDatabaseOp final
nsRefPtr<DatabaseOfflineStorage> mOfflineStorage;
// This is only set while a VersionChangeOp is live. It holds a strong
// reference to its OpenDatabaseOp object so this is a weak pointer to avoid
// cycles.
VersionChangeOp* mVersionChangeOp;
public:
OpenDatabaseOp(Factory* aFactory,
already_AddRefed<ContentParent> aContentParent,
@ -6607,7 +6612,9 @@ public:
private:
~OpenDatabaseOp()
{ }
{
MOZ_ASSERT(!mVersionChangeOp);
}
nsresult
LoadDatabaseInformation(mozIStorageConnection* aConnection);
@ -6635,6 +6642,9 @@ private:
void
ConnectionClosedCallback();
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual nsresult
QuotaManagerOpen() override;
@ -6655,9 +6665,6 @@ private:
virtual void
SendResults() override;
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
};
class OpenDatabaseOp::VersionChangeOp final
@ -6684,7 +6691,9 @@ private:
}
~VersionChangeOp()
{ }
{
MOZ_ASSERT(!mOpenDatabaseOp);
}
virtual nsresult
DoDatabaseWork(DatabaseConnection* aConnection) override;
@ -7908,7 +7917,7 @@ class DatabaseOfflineStorage final
bool mInvalidatedOnMainThread;
bool mInvalidatedOnOwningThread;
DebugOnly<bool> mRegisteredWithQuotaManager;
bool mRegisteredWithQuotaManager;
public:
DatabaseOfflineStorage(QuotaClient* aQuotaClient,
@ -7964,7 +7973,7 @@ private:
~DatabaseOfflineStorage()
{
MOZ_ASSERT(!mDatabase);
MOZ_ASSERT(!mRegisteredWithQuotaManager);
MOZ_RELEASE_ASSERT(!mRegisteredWithQuotaManager);
}
void
@ -8454,10 +8463,11 @@ DatabaseConnection::FinishWriteTransaction()
{
AssertIsOnConnectionThread();
MOZ_ASSERT(mStorageConnection);
MOZ_ASSERT(mUpdateRefcountFunction);
MOZ_ASSERT(mDEBUGInWriteTransaction);
mUpdateRefcountFunction->Reset();
if (mUpdateRefcountFunction) {
mUpdateRefcountFunction->Reset();
}
#ifdef DEBUG
mDEBUGInWriteTransaction = false;
@ -17095,6 +17105,7 @@ OpenDatabaseOp::OpenDatabaseOp(Factory* aFactory,
: FactoryOp(aFactory, Move(aContentParent), aParams, /* aDeleting */ false)
, mMetadata(new FullDatabaseMetadata(aParams.metadata()))
, mRequestedVersion(aParams.metadata().version())
, mVersionChangeOp(nullptr)
{
auto& optionalContentParentId =
const_cast<OptionalContentId&>(mOptionalContentParentId);
@ -17108,6 +17119,22 @@ OpenDatabaseOp::OpenDatabaseOp(Factory* aFactory,
}
}
void
OpenDatabaseOp::ActorDestroy(ActorDestroyReason aWhy)
{
AssertIsOnOwningThread();
if (mDatabase && aWhy != Deletion) {
mDatabase->Invalidate();
}
if (mVersionChangeOp) {
mVersionChangeOp->NoteActorDestroyed();
}
FactoryOp::ActorDestroy(aWhy);
}
nsresult
OpenDatabaseOp::QuotaManagerOpen()
{
@ -17751,6 +17778,10 @@ OpenDatabaseOp::DispatchToWorkThread()
const nsID& backgroundChildLoggingId =
mVersionChangeTransaction->GetLoggingInfo()->Id();
if (NS_WARN_IF(!mDatabase->RegisterTransaction(mVersionChangeTransaction))) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsRefPtr<VersionChangeOp> versionChangeOp = new VersionChangeOp(this);
uint64_t transactionId =
@ -17761,13 +17792,10 @@ OpenDatabaseOp::DispatchToWorkThread()
/* aIsWriteTransaction */ true,
versionChangeOp);
mVersionChangeTransaction->SetActive(transactionId);
mVersionChangeOp = versionChangeOp;
mVersionChangeTransaction->NoteActiveRequest();
if (NS_WARN_IF(!mDatabase->RegisterTransaction(mVersionChangeTransaction))) {
return NS_ERROR_OUT_OF_MEMORY;
}
mVersionChangeTransaction->SetActive(transactionId);
return NS_OK;
}
@ -17897,18 +17925,6 @@ OpenDatabaseOp::SendResults()
FinishSendResults();
}
void
OpenDatabaseOp::ActorDestroy(ActorDestroyReason aWhy)
{
AssertIsOnBackgroundThread();
NoteActorDestroyed();
if (mDatabase && aWhy != Deletion) {
mDatabase->Invalidate();
}
}
void
OpenDatabaseOp::ConnectionClosedCallback()
{
@ -18222,6 +18238,7 @@ VersionChangeOp::DoDatabaseWork(DatabaseConnection* aConnection)
{
MOZ_ASSERT(aConnection);
aConnection->AssertIsOnConnectionThread();
MOZ_ASSERT(mOpenDatabaseOp);
MOZ_ASSERT(mOpenDatabaseOp->mState == State_DatabaseWorkVersionChange);
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) ||
@ -18276,6 +18293,7 @@ VersionChangeOp::SendSuccessResult()
AssertIsOnOwningThread();
MOZ_ASSERT(mOpenDatabaseOp);
MOZ_ASSERT(mOpenDatabaseOp->mState == State_DatabaseWorkVersionChange);
MOZ_ASSERT(mOpenDatabaseOp->mVersionChangeOp == this);
nsresult rv = mOpenDatabaseOp->SendUpgradeNeeded();
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -18292,6 +18310,7 @@ VersionChangeOp::SendFailureResult(nsresult aResultCode)
AssertIsOnOwningThread();
MOZ_ASSERT(mOpenDatabaseOp);
MOZ_ASSERT(mOpenDatabaseOp->mState == State_DatabaseWorkVersionChange);
MOZ_ASSERT(mOpenDatabaseOp->mVersionChangeOp == this);
mOpenDatabaseOp->SetFailureCode(aResultCode);
mOpenDatabaseOp->mState = State_SendingResults;
@ -18306,7 +18325,10 @@ OpenDatabaseOp::
VersionChangeOp::Cleanup()
{
AssertIsOnOwningThread();
MOZ_ASSERT(mOpenDatabaseOp);
MOZ_ASSERT(mOpenDatabaseOp->mVersionChangeOp == this);
mOpenDatabaseOp->mVersionChangeOp = nullptr;
mOpenDatabaseOp = nullptr;
#ifdef DEBUG
@ -19343,13 +19365,15 @@ CommitOp::Run()
MOZ_ASSERT(database);
if (DatabaseConnection* connection = database->GetConnection()) {
// May be null if the VersionChangeOp was canceled.
DatabaseConnection::UpdateRefcountFunction* fileRefcountFunction =
connection->GetUpdateRefcountFunction();
MOZ_ASSERT(fileRefcountFunction);
if (NS_SUCCEEDED(mResultCode)) {
mResultCode = fileRefcountFunction->WillCommit();
NS_WARN_IF_FALSE(NS_SUCCEEDED(mResultCode), "WillCommit() failed!");
if (fileRefcountFunction) {
mResultCode = fileRefcountFunction->WillCommit();
NS_WARN_IF_FALSE(NS_SUCCEEDED(mResultCode), "WillCommit() failed!");
}
if (NS_SUCCEEDED(mResultCode)) {
mResultCode = WriteAutoIncrementCounts();
@ -19373,7 +19397,7 @@ CommitOp::Run()
mResultCode = connection->Checkpoint(/* aIdle */ false);
}
if (NS_SUCCEEDED(mResultCode)) {
if (NS_SUCCEEDED(mResultCode) && fileRefcountFunction) {
fileRefcountFunction->DidCommit();
}
}
@ -19382,7 +19406,9 @@ CommitOp::Run()
}
if (NS_FAILED(mResultCode)) {
fileRefcountFunction->DidAbort();
if (fileRefcountFunction) {
fileRefcountFunction->DidAbort();
}
DatabaseConnection::CachedStatement stmt;
if (NS_SUCCEEDED(connection->GetCachedStatement("ROLLBACK", &stmt))) {