Bug 1157573 - Fix transaction rollback assertions for when a transaction was never started, r=janv.

This commit is contained in:
Ben Turner 2015-04-23 15:29:15 -07:00
Родитель 8026501005
Коммит f2493adb09
1 изменённых файлов: 51 добавлений и 27 удалений

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

@ -4334,11 +4334,11 @@ private:
nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
mCachedStatements;
nsRefPtr<UpdateRefcountFunction> mUpdateRefcountFunction;
bool mInWriteTransaction;
#ifdef DEBUG
uint32_t mDEBUGSavepointCount;
PRThread* mDEBUGThread;
bool mDEBUGInWriteTransaction;
#endif
public:
@ -4389,6 +4389,9 @@ public:
nsresult
BeginWriteTransaction();
void
RollbackWriteTransaction();
void
FinishWriteTransaction();
@ -8295,10 +8298,10 @@ DatabaseConnection::DatabaseConnection(
FileManager* aFileManager)
: mStorageConnection(aStorageConnection)
, mFileManager(aFileManager)
, mInWriteTransaction(false)
#ifdef DEBUG
, mDEBUGSavepointCount(0)
, mDEBUGThread(PR_GetCurrentThread())
, mDEBUGInWriteTransaction(false)
#endif
{
AssertIsOnConnectionThread();
@ -8312,15 +8315,15 @@ DatabaseConnection::~DatabaseConnection()
MOZ_ASSERT(!mFileManager);
MOZ_ASSERT(!mCachedStatements.Count());
MOZ_ASSERT(!mUpdateRefcountFunction);
MOZ_ASSERT(!mInWriteTransaction);
MOZ_ASSERT(!mDEBUGSavepointCount);
MOZ_ASSERT(!mDEBUGInWriteTransaction);
}
nsresult
DatabaseConnection::Init()
{
AssertIsOnConnectionThread();
MOZ_ASSERT(!mDEBUGInWriteTransaction);
MOZ_ASSERT(!mInWriteTransaction);
CachedStatement stmt;
nsresult rv = GetCachedStatement("BEGIN", &stmt);
@ -8382,20 +8385,20 @@ DatabaseConnection::BeginWriteTransaction()
{
AssertIsOnConnectionThread();
MOZ_ASSERT(mStorageConnection);
MOZ_ASSERT(!mDEBUGInWriteTransaction);
MOZ_ASSERT(!mInWriteTransaction);
PROFILER_LABEL("IndexedDB",
"DatabaseConnection::BeginWriteTransaction",
js::ProfileEntry::Category::STORAGE);
// Release our read locks.
CachedStatement commitStmt;
nsresult rv = GetCachedStatement("ROLLBACK", &commitStmt);
CachedStatement rollbackStmt;
nsresult rv = GetCachedStatement("ROLLBACK", &rollbackStmt);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = commitStmt->Execute();
rv = rollbackStmt->Execute();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -8447,27 +8450,55 @@ DatabaseConnection::BeginWriteTransaction()
return rv;
}
#ifdef DEBUG
mDEBUGInWriteTransaction = true;
#endif
mInWriteTransaction = true;
return NS_OK;
}
void
DatabaseConnection::RollbackWriteTransaction()
{
AssertIsOnConnectionThread();
MOZ_ASSERT(mStorageConnection);
PROFILER_LABEL("IndexedDB",
"DatabaseConnection::RollbackWriteTransaction",
js::ProfileEntry::Category::STORAGE);
if (!mInWriteTransaction) {
return;
}
DatabaseConnection::CachedStatement stmt;
nsresult rv = GetCachedStatement("ROLLBACK", &stmt);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// This may fail if SQLite already rolled back the transaction so ignore any
// errors.
unused << stmt->Execute();
}
void
DatabaseConnection::FinishWriteTransaction()
{
AssertIsOnConnectionThread();
MOZ_ASSERT(mStorageConnection);
MOZ_ASSERT(mDEBUGInWriteTransaction);
PROFILER_LABEL("IndexedDB",
"DatabaseConnection::FinishWriteTransaction",
js::ProfileEntry::Category::STORAGE);
if (mUpdateRefcountFunction) {
mUpdateRefcountFunction->Reset();
}
#ifdef DEBUG
mDEBUGInWriteTransaction = false;
#endif
if (!mInWriteTransaction) {
return;
}
mInWriteTransaction = false;
CachedStatement stmt;
nsresult rv = GetCachedStatement("BEGIN", &stmt);
@ -8487,7 +8518,7 @@ DatabaseConnection::StartSavepoint()
AssertIsOnConnectionThread();
MOZ_ASSERT(mStorageConnection);
MOZ_ASSERT(mUpdateRefcountFunction);
MOZ_ASSERT(mDEBUGInWriteTransaction);
MOZ_ASSERT(mInWriteTransaction);
PROFILER_LABEL("IndexedDB",
"DatabaseConnection::StartSavepoint",
@ -8520,7 +8551,7 @@ DatabaseConnection::ReleaseSavepoint()
AssertIsOnConnectionThread();
MOZ_ASSERT(mStorageConnection);
MOZ_ASSERT(mUpdateRefcountFunction);
MOZ_ASSERT(mDEBUGInWriteTransaction);
MOZ_ASSERT(mInWriteTransaction);
PROFILER_LABEL("IndexedDB",
"DatabaseConnection::ReleaseSavepoint",
@ -8551,7 +8582,7 @@ DatabaseConnection::RollbackSavepoint()
AssertIsOnConnectionThread();
MOZ_ASSERT(mStorageConnection);
MOZ_ASSERT(mUpdateRefcountFunction);
MOZ_ASSERT(mDEBUGInWriteTransaction);
MOZ_ASSERT(mInWriteTransaction);
PROFILER_LABEL("IndexedDB",
"DatabaseConnection::RollbackSavepoint",
@ -8623,7 +8654,7 @@ DatabaseConnection::Close()
AssertIsOnConnectionThread();
MOZ_ASSERT(mStorageConnection);
MOZ_ASSERT(!mDEBUGSavepointCount);
MOZ_ASSERT(!mDEBUGInWriteTransaction);
MOZ_ASSERT(!mInWriteTransaction);
PROFILER_LABEL("IndexedDB",
"DatabaseConnection::Close",
@ -19406,14 +19437,7 @@ CommitOp::Run()
fileRefcountFunction->DidAbort();
}
DatabaseConnection::CachedStatement stmt;
if (NS_SUCCEEDED(connection->GetCachedStatement("ROLLBACK", &stmt))) {
// This may fail if SQLite already rolled back the transaction so
// ignore any errors.
unused << stmt->Execute();
} else {
NS_WARNING("Failed to prepare ROLLBACK statement!");
}
connection->RollbackWriteTransaction();
}
CommitOrRollbackAutoIncrementCounts();