mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Bug 1352401 - Part 2: Count active IDBOpenRequest, IndexedDB databases/transactions. r=janv
--HG-- extra : rebase_source : 87263d63be9021fe2493beb4b874c7e2749fd665
This commit is contained in:
parent
da26e6fa39
commit
d6b1d1a397
@ -2227,17 +2227,7 @@ BackgroundDatabaseChild::RecvPBackgroundIDBVersionChangeTransactionConstructor(
|
||||
request,
|
||||
aNextObjectStoreId,
|
||||
aNextIndexId);
|
||||
if (NS_WARN_IF(!transaction)) {
|
||||
// This can happen if we receive events after a worker has begun its
|
||||
// shutdown process.
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
// Report this to the console.
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
|
||||
MOZ_ALWAYS_TRUE(aActor->SendDeleteMe());
|
||||
return IPC_OK();
|
||||
}
|
||||
MOZ_ASSERT(transaction);
|
||||
|
||||
transaction->AssertIsOnOwningThread();
|
||||
|
||||
|
@ -177,6 +177,7 @@ IDBDatabase::IDBDatabase(IDBOpenDBRequest* aRequest,
|
||||
, mClosed(false)
|
||||
, mInvalidated(false)
|
||||
, mQuotaExceeded(false)
|
||||
, mIncreasedActiveDatabaseCount(false)
|
||||
{
|
||||
MOZ_ASSERT(aRequest);
|
||||
MOZ_ASSERT(aFactory);
|
||||
@ -189,6 +190,7 @@ IDBDatabase::~IDBDatabase()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!mBackgroundActor);
|
||||
MOZ_ASSERT(!mIncreasedActiveDatabaseCount);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -219,11 +221,8 @@ IDBDatabase::Create(IDBOpenDBRequest* aRequest,
|
||||
MOZ_ASSERT(obsSvc);
|
||||
|
||||
// This topic must be successfully registered.
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
obsSvc->AddObserver(observer, kWindowObserverTopic, false)))) {
|
||||
observer->Revoke();
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
obsSvc->AddObserver(observer, kWindowObserverTopic, false));
|
||||
|
||||
// These topics are not crucial.
|
||||
if (NS_FAILED(obsSvc->AddObserver(observer,
|
||||
@ -239,6 +238,8 @@ IDBDatabase::Create(IDBOpenDBRequest* aRequest,
|
||||
}
|
||||
}
|
||||
|
||||
db->IncreaseActiveDatabaseCount();
|
||||
|
||||
return db.forget();
|
||||
}
|
||||
|
||||
@ -289,6 +290,10 @@ IDBDatabase::CloseInternal()
|
||||
if (mBackgroundActor && !mInvalidated) {
|
||||
mBackgroundActor->SendClose();
|
||||
}
|
||||
|
||||
// Decrease the number of active databases right after the database is
|
||||
// closed.
|
||||
MaybeDecreaseActiveDatabaseCount();
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,10 +695,7 @@ IDBDatabase::Transaction(JSContext* aCx,
|
||||
|
||||
RefPtr<IDBTransaction> transaction =
|
||||
IDBTransaction::Create(aCx, this, sortedStoreNames, mode);
|
||||
if (NS_WARN_IF(!transaction)) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
MOZ_ASSERT(transaction);
|
||||
|
||||
BackgroundTransactionChild* actor =
|
||||
new BackgroundTransactionChild(transaction);
|
||||
@ -967,19 +969,30 @@ IDBDatabase::NoteFinishedFileActor(PBackgroundIDBDatabaseFileChild* aFileActor)
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::DelayedMaybeExpireFileActors()
|
||||
IDBDatabase::NoteActiveTransaction()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mFactory);
|
||||
|
||||
// Increase the number of active transactions.
|
||||
mFactory->UpdateActiveTransactionCount(1);
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::NoteInactiveTransaction()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (!mBackgroundActor || !mFileActors.Count()) {
|
||||
MOZ_ASSERT(mFactory);
|
||||
mFactory->UpdateActiveTransactionCount(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<Runnable> runnable =
|
||||
NewRunnableMethod<bool>("IDBDatabase::ExpireFileActors",
|
||||
this,
|
||||
&IDBDatabase::ExpireFileActors,
|
||||
/* aExpireAll */ false);
|
||||
NewRunnableMethod("IDBDatabase::NoteInactiveTransactionDelayed",
|
||||
this,
|
||||
&IDBDatabase::NoteInactiveTransactionDelayed);
|
||||
MOZ_ASSERT(runnable);
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
@ -1131,6 +1144,15 @@ IDBDatabase::Invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::NoteInactiveTransactionDelayed()
|
||||
{
|
||||
ExpireFileActors(/* aExpireAll */ false);
|
||||
|
||||
MOZ_ASSERT(mFactory);
|
||||
mFactory->UpdateActiveTransactionCount(-1);
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::LogWarning(const char* aMessageName,
|
||||
const nsAString& aFilename,
|
||||
@ -1352,5 +1374,29 @@ IDBDatabase::RenameIndex(int64_t aObjectStoreId,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::IncreaseActiveDatabaseCount()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mFactory);
|
||||
MOZ_ASSERT(!mIncreasedActiveDatabaseCount);
|
||||
|
||||
mFactory->UpdateActiveDatabaseCount(1);
|
||||
mIncreasedActiveDatabaseCount = true;
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::MaybeDecreaseActiveDatabaseCount()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (mIncreasedActiveDatabaseCount) {
|
||||
// Decrease the number of active databases.
|
||||
MOZ_ASSERT(mFactory);
|
||||
mFactory->UpdateActiveDatabaseCount(-1);
|
||||
mIncreasedActiveDatabaseCount = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -86,6 +86,7 @@ class IDBDatabase final
|
||||
bool mClosed;
|
||||
bool mInvalidated;
|
||||
bool mQuotaExceeded;
|
||||
bool mIncreasedActiveDatabaseCount;
|
||||
|
||||
public:
|
||||
static already_AddRefed<IDBDatabase>
|
||||
@ -192,7 +193,10 @@ public:
|
||||
NoteFinishedFileActor(indexedDB::PBackgroundIDBDatabaseFileChild* aFileActor);
|
||||
|
||||
void
|
||||
DelayedMaybeExpireFileActors();
|
||||
NoteActiveTransaction();
|
||||
|
||||
void
|
||||
NoteInactiveTransaction();
|
||||
|
||||
// XXX This doesn't really belong here... It's only needed for IDBMutableFile
|
||||
// serialization and should be removed or fixed someday.
|
||||
@ -267,6 +271,10 @@ public:
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// Decrease the number of active databases if it was not done in
|
||||
// CloseInternal().
|
||||
MaybeDecreaseActiveDatabaseCount();
|
||||
|
||||
mBackgroundActor = nullptr;
|
||||
}
|
||||
|
||||
@ -321,6 +329,9 @@ private:
|
||||
void
|
||||
InvalidateMutableFiles();
|
||||
|
||||
void
|
||||
NoteInactiveTransactionDelayed();
|
||||
|
||||
void
|
||||
LogWarning(const char* aMessageName,
|
||||
const nsAString& aFilename,
|
||||
@ -334,6 +345,12 @@ private:
|
||||
// Only accessed by IDBIndex.
|
||||
nsresult
|
||||
RenameIndex(int64_t aObjectStoreId, int64_t aIndexId, const nsAString& aName);
|
||||
|
||||
void
|
||||
IncreaseActiveDatabaseCount();
|
||||
|
||||
void
|
||||
MaybeDecreaseActiveDatabaseCount();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -162,13 +162,17 @@ IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
|
||||
|
||||
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
|
||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
|
||||
RefPtr<nsGlobalWindow> globalWindow = nsGlobalWindow::Cast(aWindow);
|
||||
MOZ_ASSERT(globalWindow);
|
||||
nsCOMPtr<nsPIDOMWindowOuter> topOutterWindow = globalWindow->GetScriptableTop();
|
||||
MOZ_ASSERT(topOutterWindow);
|
||||
|
||||
RefPtr<IDBFactory> factory = new IDBFactory();
|
||||
factory->mPrincipalInfo = Move(principalInfo);
|
||||
factory->mWindow = aWindow;
|
||||
factory->mTopWindow = topOutterWindow->GetCurrentInnerWindow();
|
||||
factory->mTabChild = TabChild::GetFrom(aWindow);
|
||||
factory->mEventTarget =
|
||||
nsGlobalWindow::Cast(aWindow)->EventTargetFor(TaskCategory::Other);
|
||||
factory->mEventTarget = globalWindow->EventTargetFor(TaskCategory::Other);
|
||||
factory->mInnerWindowID = aWindow->WindowID();
|
||||
factory->mPrivateBrowsingMode =
|
||||
loadContext && loadContext->UsePrivateBrowsing();
|
||||
@ -417,6 +421,24 @@ IDBFactory::AllowedForPrincipal(nsIPrincipal* aPrincipal,
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
IDBFactory::UpdateActiveTransactionCount(int32_t aDelta)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
if (mTopWindow) {
|
||||
mTopWindow->UpdateActiveIndexedDBTransactionCount(aDelta);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IDBFactory::UpdateActiveDatabaseCount(int32_t aDelta)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
if (mTopWindow) {
|
||||
mTopWindow->UpdateActiveIndexedDBDatabaseCount(aDelta);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IDBFactory::IsChrome() const
|
||||
{
|
||||
@ -892,12 +914,14 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBFactory)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBFactory)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTopWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBFactory)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
tmp->mOwningObject = nullptr;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTopWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBFactory)
|
||||
|
@ -60,9 +60,10 @@ class IDBFactory final
|
||||
|
||||
nsAutoPtr<PrincipalInfo> mPrincipalInfo;
|
||||
|
||||
// If this factory lives on a window then mWindow must be non-null. Otherwise
|
||||
// mOwningObject must be non-null.
|
||||
// If this factory lives on a window then m(Top)Window must be non-null.
|
||||
// Otherwise mOwningObject must be non-null.
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
nsCOMPtr<nsPIDOMWindowInner> mTopWindow;
|
||||
JS::Heap<JSObject*> mOwningObject;
|
||||
|
||||
// This will only be set if the factory belongs to a window in a child
|
||||
@ -129,6 +130,20 @@ public:
|
||||
mBackgroundActor = nullptr;
|
||||
}
|
||||
|
||||
// Increase/Decrease the number of active transactions for the decision
|
||||
// making of preemption and throttling.
|
||||
// Note: If the state of its actor is not committed or aborted, it could block
|
||||
// IDB operations in other window.
|
||||
void
|
||||
UpdateActiveTransactionCount(int32_t aDelta);
|
||||
|
||||
// Increase/Decrease the number of active databases and IDBOpenRequests for
|
||||
// the decision making of preemption and throttling.
|
||||
// Note: A non-closed database or a pending IDBOpenRequest could block
|
||||
// IDB operations in other window.
|
||||
void
|
||||
UpdateActiveDatabaseCount(int32_t aDelta);
|
||||
|
||||
void
|
||||
IncrementParentLoggingRequestSerialNumber();
|
||||
|
||||
|
@ -210,29 +210,6 @@ IDBRequest::Reset()
|
||||
mError = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
IDBRequest::DispatchNonTransactionError(nsresult aErrorCode)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(NS_FAILED(aErrorCode));
|
||||
MOZ_ASSERT(NS_ERROR_GET_MODULE(aErrorCode) == NS_ERROR_MODULE_DOM_INDEXEDDB);
|
||||
|
||||
SetError(aErrorCode);
|
||||
|
||||
// Make an error event and fire it at the target.
|
||||
nsCOMPtr<nsIDOMEvent> event =
|
||||
CreateGenericEvent(this,
|
||||
nsDependentString(kErrorEventType),
|
||||
eDoesBubble,
|
||||
eCancelable);
|
||||
MOZ_ASSERT(event);
|
||||
|
||||
bool ignored;
|
||||
if (NS_FAILED(DispatchEvent(event, &ignored))) {
|
||||
NS_WARNING("Failed to dispatch event!");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IDBRequest::SetError(nsresult aRv)
|
||||
{
|
||||
@ -491,6 +468,7 @@ IDBOpenDBRequest::IDBOpenDBRequest(IDBFactory* aFactory,
|
||||
: IDBRequest(aOwner)
|
||||
, mFactory(aFactory)
|
||||
, mFileHandleDisabled(aFileHandleDisabled)
|
||||
, mIncreasedActiveDatabaseCount(false)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aFactory);
|
||||
@ -501,6 +479,7 @@ IDBOpenDBRequest::IDBOpenDBRequest(IDBFactory* aFactory,
|
||||
IDBOpenDBRequest::~IDBOpenDBRequest()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!mIncreasedActiveDatabaseCount);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -523,6 +502,8 @@ IDBOpenDBRequest::CreateForWindow(JSContext* aCx,
|
||||
|
||||
request->SetScriptOwner(aScriptOwner);
|
||||
|
||||
request->IncreaseActiveDatabaseCount();
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
@ -559,6 +540,8 @@ IDBOpenDBRequest::CreateForJS(JSContext* aCx,
|
||||
request->mWorkerHolder = Move(workerHolder);
|
||||
}
|
||||
|
||||
request->IncreaseActiveDatabaseCount();
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
@ -572,17 +555,74 @@ IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
|
||||
mTransaction = aTransaction;
|
||||
}
|
||||
|
||||
void
|
||||
IDBOpenDBRequest::DispatchNonTransactionError(nsresult aErrorCode)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(NS_FAILED(aErrorCode));
|
||||
MOZ_ASSERT(NS_ERROR_GET_MODULE(aErrorCode) == NS_ERROR_MODULE_DOM_INDEXEDDB);
|
||||
|
||||
// The actor failed to initiate, decrease the number of active IDBOpenRequests
|
||||
// here since NoteComplete won't be called.
|
||||
MaybeDecreaseActiveDatabaseCount();
|
||||
|
||||
SetError(aErrorCode);
|
||||
|
||||
// Make an error event and fire it at the target.
|
||||
nsCOMPtr<nsIDOMEvent> event =
|
||||
CreateGenericEvent(this,
|
||||
nsDependentString(kErrorEventType),
|
||||
eDoesBubble,
|
||||
eCancelable);
|
||||
MOZ_ASSERT(event);
|
||||
|
||||
bool ignored;
|
||||
if (NS_FAILED(DispatchEvent(event, &ignored))) {
|
||||
NS_WARNING("Failed to dispatch event!");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IDBOpenDBRequest::NoteComplete()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerHolder);
|
||||
|
||||
// Normally, we decrease the number of active IDBOpenRequests here.
|
||||
MaybeDecreaseActiveDatabaseCount();
|
||||
|
||||
// If we have a WorkerHolder installed on the worker then nulling this out
|
||||
// will uninstall it from the worker.
|
||||
mWorkerHolder = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
IDBOpenDBRequest::IncreaseActiveDatabaseCount()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!mIncreasedActiveDatabaseCount);
|
||||
|
||||
// Increase the number of active IDBOpenRequests.
|
||||
// Note: We count here instead of the actor's ctor because the preemption
|
||||
// could happen at next JS interrupt but its BackgroundFactoryRequestChild
|
||||
// could be created asynchronously from IDBFactory::BackgroundCreateCallback
|
||||
// ::ActorCreated() if its PBackgroundChild is not created yet on this thread.
|
||||
mFactory->UpdateActiveDatabaseCount(1);
|
||||
mIncreasedActiveDatabaseCount = true;
|
||||
}
|
||||
|
||||
void
|
||||
IDBOpenDBRequest::MaybeDecreaseActiveDatabaseCount()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (mIncreasedActiveDatabaseCount) {
|
||||
// Decrease the number of active IDBOpenRequests.
|
||||
mFactory->UpdateActiveDatabaseCount(-1);
|
||||
mIncreasedActiveDatabaseCount = false;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBOpenDBRequest)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBOpenDBRequest,
|
||||
|
@ -93,9 +93,6 @@ public:
|
||||
void
|
||||
Reset();
|
||||
|
||||
void
|
||||
DispatchNonTransactionError(nsresult aErrorCode);
|
||||
|
||||
void
|
||||
SetResultCallback(ResultCallback* aCallback);
|
||||
|
||||
@ -227,6 +224,7 @@ class IDBOpenDBRequest final
|
||||
nsAutoPtr<WorkerHolder> mWorkerHolder;
|
||||
|
||||
const bool mFileHandleDisabled;
|
||||
bool mIncreasedActiveDatabaseCount;
|
||||
|
||||
public:
|
||||
static already_AddRefed<IDBOpenDBRequest>
|
||||
@ -249,6 +247,9 @@ public:
|
||||
void
|
||||
SetTransaction(IDBTransaction* aTransaction);
|
||||
|
||||
void
|
||||
DispatchNonTransactionError(nsresult aErrorCode);
|
||||
|
||||
void
|
||||
NoteComplete();
|
||||
|
||||
@ -278,6 +279,12 @@ private:
|
||||
bool aFileHandleDisabled);
|
||||
|
||||
~IDBOpenDBRequest();
|
||||
|
||||
void
|
||||
IncreaseActiveDatabaseCount();
|
||||
|
||||
void
|
||||
MaybeDecreaseActiveDatabaseCount();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -88,6 +88,7 @@ IDBTransaction::IDBTransaction(IDBDatabase* aDatabase,
|
||||
, mCreating(false)
|
||||
, mRegistered(false)
|
||||
, mAbortedByScript(false)
|
||||
, mNotedActiveTransaction(false)
|
||||
#ifdef DEBUG
|
||||
, mSentCommitOrAbort(false)
|
||||
, mFiredCompleteOrAbort(false)
|
||||
@ -134,6 +135,7 @@ IDBTransaction::~IDBTransaction()
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!mPendingRequestCount);
|
||||
MOZ_ASSERT(!mCreating);
|
||||
MOZ_ASSERT(!mNotedActiveTransaction);
|
||||
MOZ_ASSERT(mSentCommitOrAbort);
|
||||
MOZ_ASSERT_IF(mMode == VERSION_CHANGE &&
|
||||
mBackgroundActor.mVersionChangeBackgroundActor,
|
||||
@ -194,6 +196,8 @@ IDBTransaction::CreateVersionChange(
|
||||
nsCOMPtr<nsIRunnable> runnable = do_QueryObject(transaction);
|
||||
nsContentUtils::RunInMetastableState(runnable.forget());
|
||||
|
||||
transaction->NoteActiveTransaction();
|
||||
|
||||
transaction->mBackgroundActor.mVersionChangeBackgroundActor = aActor;
|
||||
transaction->mNextObjectStoreId = aNextObjectStoreId;
|
||||
transaction->mNextIndexId = aNextIndexId;
|
||||
@ -284,6 +288,8 @@ IDBTransaction::SetBackgroundActor(indexedDB::BackgroundTransactionChild* aBackg
|
||||
MOZ_ASSERT(!mBackgroundActor.mNormalBackgroundActor);
|
||||
MOZ_ASSERT(mMode != VERSION_CHANGE);
|
||||
|
||||
NoteActiveTransaction();
|
||||
|
||||
mBackgroundActor.mNormalBackgroundActor = aBackgroundActor;
|
||||
}
|
||||
|
||||
@ -474,6 +480,27 @@ IDBTransaction::SendAbort(nsresult aResultCode)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
IDBTransaction::NoteActiveTransaction()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!mNotedActiveTransaction);
|
||||
|
||||
mDatabase->NoteActiveTransaction();
|
||||
mNotedActiveTransaction = true;
|
||||
}
|
||||
|
||||
void
|
||||
IDBTransaction::MaybeNoteInactiveTransaction()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (mNotedActiveTransaction) {
|
||||
mDatabase->NoteInactiveTransaction();
|
||||
mNotedActiveTransaction = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IDBTransaction::IsOpen() const
|
||||
{
|
||||
@ -834,7 +861,15 @@ IDBTransaction::FireCompleteOrAbortEvents(nsresult aResult)
|
||||
NS_WARNING("DispatchEvent failed!");
|
||||
}
|
||||
|
||||
mDatabase->DelayedMaybeExpireFileActors();
|
||||
// Normally, we note inactive transaction here instead of
|
||||
// IDBTransaction::ClearBackgroundActor() because here is the earliest place
|
||||
// to know that it becomes non-blocking to allow the scheduler to start the
|
||||
// preemption as soon as it can.
|
||||
// Note: If the IDBTransaction object is held by the script,
|
||||
// ClearBackgroundActor() will be done in ~IDBTransaction() until garbage
|
||||
// collected after its window is closed which prevents us to preempt its
|
||||
// window immediately after committed.
|
||||
MaybeNoteInactiveTransaction();
|
||||
}
|
||||
|
||||
int64_t
|
||||
|
@ -109,6 +109,7 @@ private:
|
||||
bool mCreating;
|
||||
bool mRegistered;
|
||||
bool mAbortedByScript;
|
||||
bool mNotedActiveTransaction;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool mSentCommitOrAbort;
|
||||
@ -152,6 +153,10 @@ public:
|
||||
} else {
|
||||
mBackgroundActor.mNormalBackgroundActor = nullptr;
|
||||
}
|
||||
|
||||
// Note inactive transaction here if we didn't receive the Complete message
|
||||
// from the parent.
|
||||
MaybeNoteInactiveTransaction();
|
||||
}
|
||||
|
||||
indexedDB::BackgroundRequestChild*
|
||||
@ -331,6 +336,12 @@ private:
|
||||
void
|
||||
SendAbort(nsresult aResultCode);
|
||||
|
||||
void
|
||||
NoteActiveTransaction();
|
||||
|
||||
void
|
||||
MaybeNoteInactiveTransaction();
|
||||
|
||||
void
|
||||
OnNewRequest();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user