Bug 1546723 - Part 6: Mark snapshot as dirty if the hasOtherProcessObservers flag changes; r=asuth

Differential Revision: https://phabricator.services.mozilla.com/D31201
This commit is contained in:
Jan Varga 2019-05-15 06:11:11 +02:00
Родитель 55c0e5ec44
Коммит f122f3cf74
2 изменённых файлов: 70 добавлений и 3 удалений

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

@ -83,6 +83,7 @@ class ArchivedOriginScope;
class Connection;
class ConnectionThread;
class Database;
class Observer;
class PrepareDatastoreOp;
class PreparedDatastore;
class QuotaClient;
@ -1776,6 +1777,8 @@ class Datastore final
const LSValue& aOldValue,
const LSValue& aNewValue);
void NoteChangedObserverArray(const nsTArray<Observer*>& aObservers);
NS_INLINE_DECL_REFCOUNTING(Datastore)
private:
@ -2068,6 +2071,8 @@ class Snapshot final : public PBackgroundLSSnapshotParent {
bool mLoadKeysReceived;
bool mSentMarkDirty;
bool mHasOtherProcessObservers;
public:
// Created in AllocPBackgroundLSSnapshotParent.
Snapshot(Database* aDatabase, const nsAString& aDocumentURI);
@ -2076,7 +2081,7 @@ class Snapshot final : public PBackgroundLSSnapshotParent {
nsTHashtable<nsStringHashKey>& aUnknownItems,
uint32_t aNextLoadIndex, uint32_t aTotalLength,
int64_t aInitialUsage, int64_t aPeakUsage,
LSSnapshot::LoadState aLoadState) {
LSSnapshot::LoadState aLoadState, bool aHasOtherProcessObservers) {
AssertIsOnBackgroundThread();
MOZ_ASSERT(aInitialUsage >= 0);
MOZ_ASSERT(aPeakUsage >= aInitialUsage);
@ -2103,6 +2108,7 @@ class Snapshot final : public PBackgroundLSSnapshotParent {
mLoadedAllItems = true;
mLoadKeysReceived = true;
}
mHasOtherProcessObservers = aHasOtherProcessObservers;
}
/**
@ -2115,6 +2121,18 @@ class Snapshot final : public PBackgroundLSSnapshotParent {
void MarkDirty();
bool IsDirty() const {
AssertIsOnBackgroundThread();
return mSentMarkDirty;
}
bool HasOtherProcessObservers() const {
AssertIsOnBackgroundThread();
return mHasOtherProcessObservers;
}
NS_INLINE_DECL_REFCOUNTING(mozilla::dom::Snapshot)
private:
@ -3301,6 +3319,10 @@ bool RecvPBackgroundLSObserverConstructor(PBackgroundLSObserverParent* aActor,
}
array->AppendElement(observer);
if (RefPtr<Datastore> datastore = GetDatastore(observer->Origin())) {
datastore->NoteChangedObserverArray(*array);
}
return true;
}
@ -5404,6 +5426,37 @@ void Datastore::NotifyOtherProcessObservers(Database* aDatabase,
}
}
void Datastore::NoteChangedObserverArray(
const nsTArray<Observer*>& aObservers) {
AssertIsOnBackgroundThread();
for (auto iter = mActiveDatabases.ConstIter(); !iter.Done(); iter.Next()) {
Database* database = iter.Get()->GetKey();
Snapshot* snapshot = database->GetSnapshot();
MOZ_ASSERT(snapshot);
if (snapshot->IsDirty()) {
continue;
}
bool hasOtherProcessObservers = false;
PBackgroundParent* databaseBackgroundActor = database->Manager();
for (Observer* observer : aObservers) {
if (observer->Manager() != databaseBackgroundActor) {
hasOtherProcessObservers = true;
break;
}
}
if (snapshot->HasOtherProcessObservers() != hasOtherProcessObservers) {
snapshot->MarkDirty();
}
}
}
bool Datastore::UpdateUsage(int64_t aDelta) {
AssertIsOnBackgroundThread();
@ -5746,7 +5799,7 @@ mozilla::ipc::IPCResult Database::RecvPBackgroundLSSnapshotConstructor(
bool hasOtherProcessObservers = mDatastore->HasOtherProcessObservers(this);
snapshot->Init(loadedItems, unknownItems, nextLoadIndex, totalLength,
initialUsage, peakUsage, loadState);
initialUsage, peakUsage, loadState, hasOtherProcessObservers);
RegisterSnapshot(snapshot);
@ -5877,6 +5930,11 @@ mozilla::ipc::IPCResult Snapshot::RecvCheckpoint(
return IPC_FAIL_NO_REASON(this);
}
if (NS_WARN_IF(mHasOtherProcessObservers)) {
ASSERT_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
}
mDatastore->BeginUpdateBatch(mUsage);
for (uint32_t index = 0; index < aWriteInfos.Length(); index++) {
@ -5926,6 +5984,11 @@ mozilla::ipc::IPCResult Snapshot::RecvCheckpointAndNotify(
return IPC_FAIL_NO_REASON(this);
}
if (NS_WARN_IF(!mHasOtherProcessObservers)) {
ASSERT_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
}
mDatastore->BeginUpdateBatch(mUsage);
for (uint32_t index = 0; index < aWriteAndNotifyInfos.Length(); index++) {
@ -6273,6 +6336,10 @@ void Observer::ActorDestroy(ActorDestroyReason aWhy) {
array->RemoveElement(this);
if (RefPtr<Datastore> datastore = GetDatastore(mOrigin)) {
datastore->NoteChangedObserverArray(*array);
}
if (array->IsEmpty()) {
gObservers->Remove(mOrigin);
}

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

@ -1292,7 +1292,7 @@ pref("dom.storage.default_quota", 5120);
pref("dom.storage.shadow_writes", true);
pref("dom.storage.snapshot_prefill", 16384);
pref("dom.storage.snapshot_gradual_prefill", 4096);
pref("dom.storage.snapshot_reusing", false);
pref("dom.storage.snapshot_reusing", true);
pref("dom.storage.testing", false);
pref("dom.storage.client_validation", true);