зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1708705 - Handle transaction abort during value clone. r=dom-storage-reviewers,jstutte
Differential Revision: https://phabricator.services.mozilla.com/D125509
This commit is contained in:
Родитель
6a8f34efee
Коммит
a60d89964e
|
@ -774,18 +774,18 @@ RefPtr<IDBRequest> IDBObjectStore::AddOrPut(JSContext* aCx,
|
||||||
StructuredCloneWriteInfo cloneWriteInfo(mTransaction->Database());
|
StructuredCloneWriteInfo cloneWriteInfo(mTransaction->Database());
|
||||||
nsTArray<IndexUpdateInfo> updateInfos;
|
nsTArray<IndexUpdateInfo> updateInfos;
|
||||||
|
|
||||||
{
|
// According to spec https://w3c.github.io/IndexedDB/#clone-value,
|
||||||
const auto autoStateRestore =
|
// the transaction must be in inactive state during clone
|
||||||
mTransaction->TemporarilyTransitionToInactive();
|
mTransaction->TransitionToInactive();
|
||||||
GetAddInfo(aCx, aValueWrapper, aKey, cloneWriteInfo, key, updateInfos, aRv);
|
GetAddInfo(aCx, aValueWrapper, aKey, cloneWriteInfo, key, updateInfos, aRv);
|
||||||
}
|
if (mTransaction
|
||||||
|
->IsAborted()) { // No error thrown, abort is a possible outcome
|
||||||
if (aRv.Failed()) {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
MOZ_ASSERT(mTransaction->IsInactive());
|
||||||
|
mTransaction->TransitionToActive();
|
||||||
|
|
||||||
if (!mTransaction->IsActive()) {
|
if (aRv.Failed()) {
|
||||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -453,18 +453,6 @@ void IDBTransaction::MaybeNoteInactiveTransaction() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBTransaction::AutoRestoreState<IDBTransaction::ReadyState::Inactive,
|
|
||||||
IDBTransaction::ReadyState::Active>
|
|
||||||
IDBTransaction::TemporarilyTransitionToActive() {
|
|
||||||
return AutoRestoreState<ReadyState::Inactive, ReadyState::Active>{*this};
|
|
||||||
}
|
|
||||||
|
|
||||||
IDBTransaction::AutoRestoreState<IDBTransaction::ReadyState::Active,
|
|
||||||
IDBTransaction::ReadyState::Inactive>
|
|
||||||
IDBTransaction::TemporarilyTransitionToInactive() {
|
|
||||||
return AutoRestoreState<ReadyState::Active, ReadyState::Inactive>{*this};
|
|
||||||
}
|
|
||||||
|
|
||||||
void IDBTransaction::GetCallerLocation(nsAString& aFilename,
|
void IDBTransaction::GetCallerLocation(nsAString& aFilename,
|
||||||
uint32_t* const aLineNo,
|
uint32_t* const aLineNo,
|
||||||
uint32_t* const aColumn) const {
|
uint32_t* const aColumn) const {
|
||||||
|
|
|
@ -208,39 +208,6 @@ class IDBTransaction final
|
||||||
bool WasExplicitlyCommitted() const { return mWasExplicitlyCommitted; }
|
bool WasExplicitlyCommitted() const { return mWasExplicitlyCommitted; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <ReadyState OriginalState, ReadyState TemporaryState>
|
|
||||||
class AutoRestoreState {
|
|
||||||
public:
|
|
||||||
explicit AutoRestoreState(IDBTransaction& aOwner) : mOwner { aOwner }
|
|
||||||
#ifdef DEBUG
|
|
||||||
, mSavedPendingRequestCount { mOwner.mPendingRequestCount }
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
mOwner.AssertIsOnOwningThread();
|
|
||||||
MOZ_ASSERT(mOwner.mReadyState == OriginalState);
|
|
||||||
mOwner.mReadyState = TemporaryState;
|
|
||||||
}
|
|
||||||
|
|
||||||
~AutoRestoreState() {
|
|
||||||
mOwner.AssertIsOnOwningThread();
|
|
||||||
MOZ_ASSERT(mOwner.mReadyState == TemporaryState);
|
|
||||||
MOZ_ASSERT(mOwner.mPendingRequestCount == mSavedPendingRequestCount);
|
|
||||||
|
|
||||||
mOwner.mReadyState = OriginalState;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
IDBTransaction& mOwner;
|
|
||||||
#ifdef DEBUG
|
|
||||||
const uint32_t mSavedPendingRequestCount;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
AutoRestoreState<ReadyState::Inactive, ReadyState::Active>
|
|
||||||
TemporarilyTransitionToActive();
|
|
||||||
AutoRestoreState<ReadyState::Active, ReadyState::Inactive>
|
|
||||||
TemporarilyTransitionToInactive();
|
|
||||||
|
|
||||||
void TransitionToActive() {
|
void TransitionToActive() {
|
||||||
MOZ_ASSERT(mReadyState == ReadyState::Inactive);
|
MOZ_ASSERT(mReadyState == ReadyState::Inactive);
|
||||||
mReadyState = ReadyState::Active;
|
mReadyState = ReadyState::Active;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче