Bug 1919555 - LSNG: Convert PBackgroundLSDatabase to a top level actor; r=dom-storage-reviewers,asuth
The conversion will allow: - returning an endpoint instead of a datastore id when datastore preparation is done - binding the child actor to a different event target Long term, it would be possible to bind the parent actor to a dedicated task queue or existing LS thread, helping to relieve the PBackground thread. Differential Revision: https://phabricator.services.mozilla.com/D222417
This commit is contained in:
@@ -38,14 +38,14 @@ LSDatabaseChild::~LSDatabaseChild() {
|
||||
MOZ_COUNT_DTOR(LSDatabaseChild);
|
||||
}
|
||||
|
||||
void LSDatabaseChild::SendDelete() {
|
||||
void LSDatabaseChild::Shutdown() {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (mDatabase) {
|
||||
mDatabase->ClearActor();
|
||||
mDatabase = nullptr;
|
||||
|
||||
MOZ_ALWAYS_TRUE(PBackgroundLSDatabaseChild::Send__delete__(this));
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,16 +45,16 @@ class LSSnapshot;
|
||||
* Most of the interesting bits happen via PBackgroundLSSnapshot.
|
||||
*
|
||||
* Mutual raw pointers are maintained between LSDatabase and this class that are
|
||||
* cleared at either (expected) when the child starts the deletion process
|
||||
* (SendDelete) or unexpected actor death (ActorDestroy).
|
||||
* cleared at either (expected) when the child starts the shutdown process
|
||||
* (Shutdown) or unexpected actor death (ActorDestroy).
|
||||
*
|
||||
* See `PBackgroundLSDatabase.ipdl` for more information.
|
||||
*
|
||||
*
|
||||
* ## Low-Level Lifecycle ##
|
||||
* - Created by LSObject::EnsureDatabase if it had to create a database.
|
||||
* - Deletion begun by LSDatabase's destructor invoking SendDelete which sends
|
||||
* __delete__ which destroys the actor.
|
||||
* - Shutdown begun by LSDatabase's destructor invoking Shutdown which destroys
|
||||
* the actor.
|
||||
*/
|
||||
class LSDatabaseChild final : public PBackgroundLSDatabaseChild {
|
||||
friend class mozilla::ipc::BackgroundChildImpl;
|
||||
@@ -76,7 +76,7 @@ class LSDatabaseChild final : public PBackgroundLSDatabaseChild {
|
||||
|
||||
~LSDatabaseChild();
|
||||
|
||||
void SendDelete();
|
||||
void Shutdown();
|
||||
|
||||
// IPDL methods are only called by IPDL.
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
@@ -2791,6 +2791,10 @@ using PrivateDatastoreHashtable =
|
||||
// window actually goes away.
|
||||
UniquePtr<PrivateDatastoreHashtable> gPrivateDatastores;
|
||||
|
||||
using DatabaseArray = nsTArray<Database*>;
|
||||
|
||||
StaticAutoPtr<DatabaseArray> gDatabases;
|
||||
|
||||
using LiveDatabaseArray = nsTArray<NotNull<CheckedUnsafePtr<Database>>>;
|
||||
|
||||
StaticAutoPtr<LiveDatabaseArray> gLiveDatabases;
|
||||
@@ -3202,6 +3206,8 @@ void InitializeLocalStorage() {
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
already_AddRefed<PBackgroundLSDatabaseParent> AllocPBackgroundLSDatabaseParent(
|
||||
const PrincipalInfo& aPrincipalInfo, const uint32_t& aPrivateBrowsingId,
|
||||
const uint64_t& aDatastoreId) {
|
||||
@@ -3225,14 +3231,14 @@ already_AddRefed<PBackgroundLSDatabaseParent> AllocPBackgroundLSDatabaseParent(
|
||||
// If we ever decide to return null from this point on, we need to make sure
|
||||
// that the datastore is closed and the prepared datastore is removed from the
|
||||
// gPreparedDatastores hashtable.
|
||||
// We also assume that IPDL must call RecvPBackgroundLSDatabaseConstructor
|
||||
// once we return a valid actor in this method.
|
||||
// We also assume that RecvCreateBackgroundLSDatabaseParent must call
|
||||
// RecvPBackgroundLSDatabaseConstructor once we return a valid actor in this
|
||||
// method.
|
||||
|
||||
RefPtr<Database> database =
|
||||
new Database(aPrincipalInfo, preparedDatastore->GetContentParentId(),
|
||||
preparedDatastore->Origin(), aPrivateBrowsingId);
|
||||
|
||||
// Transfer ownership to IPDL.
|
||||
return database.forget();
|
||||
}
|
||||
|
||||
@@ -3246,8 +3252,8 @@ bool RecvPBackgroundLSDatabaseConstructor(PBackgroundLSDatabaseParent* aActor,
|
||||
MOZ_ASSERT(gPreparedDatastores->Get(aDatastoreId));
|
||||
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnBackgroundThread());
|
||||
|
||||
// The actor is now completely built (it has a manager, channel and it's
|
||||
// registered as a subprotocol).
|
||||
// The actor is now completely built (it has a channel and it's registered
|
||||
// as a top level protocol).
|
||||
// ActorDestroy will be called if we fail here.
|
||||
|
||||
mozilla::UniquePtr<PreparedDatastore> preparedDatastore;
|
||||
@@ -3268,6 +3274,25 @@ bool RecvPBackgroundLSDatabaseConstructor(PBackgroundLSDatabaseParent* aActor,
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool RecvCreateBackgroundLSDatabaseParent(
|
||||
const PrincipalInfo& aPrincipalInfo, const uint32_t& aPrivateBrowsingId,
|
||||
const uint64_t& aDatastoreId,
|
||||
Endpoint<PBackgroundLSDatabaseParent>&& aParentEndpoint) {
|
||||
RefPtr<PBackgroundLSDatabaseParent> parent = AllocPBackgroundLSDatabaseParent(
|
||||
aPrincipalInfo, aPrivateBrowsingId, aDatastoreId);
|
||||
if (!parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Transfer ownership to IPDL.
|
||||
MOZ_ALWAYS_TRUE(aParentEndpoint.Bind(parent));
|
||||
|
||||
return RecvPBackgroundLSDatabaseConstructor(parent, aPrincipalInfo,
|
||||
aPrivateBrowsingId, aDatastoreId);
|
||||
}
|
||||
|
||||
PBackgroundLSObserverParent* AllocPBackgroundLSObserverParent(
|
||||
const uint64_t& aObserverId) {
|
||||
AssertIsOnBackgroundThread();
|
||||
@@ -5305,12 +5330,25 @@ Database::Database(const PrincipalInfo& aPrincipalInfo,
|
||||
#endif
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (!gDatabases) {
|
||||
gDatabases = new DatabaseArray();
|
||||
}
|
||||
|
||||
gDatabases->AppendElement(this);
|
||||
}
|
||||
|
||||
Database::~Database() {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT_IF(mActorWasAlive, mAllowedToClose);
|
||||
MOZ_ASSERT_IF(mActorWasAlive, mActorDestroyed);
|
||||
|
||||
MOZ_ASSERT(gDatabases);
|
||||
gDatabases->RemoveElement(this);
|
||||
|
||||
if (gDatabases->IsEmpty()) {
|
||||
gDatabases = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Database::SetActorAlive(Datastore* aDatastore) {
|
||||
@@ -5387,7 +5425,7 @@ void Database::ForceKill() {
|
||||
return;
|
||||
}
|
||||
|
||||
Unused << PBackgroundLSDatabaseParent::Send__delete__(this);
|
||||
Close();
|
||||
}
|
||||
|
||||
void Database::Stringify(nsACString& aResult) const {
|
||||
@@ -5398,7 +5436,7 @@ void Database::Stringify(nsACString& aResult) const {
|
||||
aResult.Append(kQuotaGenericDelimiter);
|
||||
|
||||
aResult.AppendLiteral("OtherProcessActor:");
|
||||
aResult.AppendInt(BackgroundParent::IsOtherProcessActor(Manager()));
|
||||
aResult.AppendInt(mContentParentId.isSome());
|
||||
aResult.Append(kQuotaGenericDelimiter);
|
||||
|
||||
aResult.AppendLiteral("Origin:");
|
||||
@@ -8859,6 +8897,18 @@ void QuotaClient::FinalizeShutdown() {
|
||||
|
||||
gConnectionThread = nullptr;
|
||||
}
|
||||
|
||||
if (gDatabases) {
|
||||
nsTArray<RefPtr<Database>> databases;
|
||||
|
||||
for (const auto& database : *gDatabases) {
|
||||
databases.AppendElement(database);
|
||||
}
|
||||
|
||||
for (const auto& database : databases) {
|
||||
database->Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Result<UniquePtr<ArchivedOriginScope>, nsresult>
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace mozilla {
|
||||
|
||||
namespace ipc {
|
||||
|
||||
template <class T>
|
||||
class Endpoint;
|
||||
class PBackgroundParent;
|
||||
class PrincipalInfo;
|
||||
|
||||
@@ -36,14 +38,10 @@ class Client;
|
||||
|
||||
void InitializeLocalStorage();
|
||||
|
||||
already_AddRefed<PBackgroundLSDatabaseParent> AllocPBackgroundLSDatabaseParent(
|
||||
bool RecvCreateBackgroundLSDatabaseParent(
|
||||
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
|
||||
const uint32_t& aPrivateBrowsingId, const uint64_t& aDatastoreId);
|
||||
|
||||
bool RecvPBackgroundLSDatabaseConstructor(
|
||||
PBackgroundLSDatabaseParent* aActor,
|
||||
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
|
||||
const uint32_t& aPrivateBrowsingId, const uint64_t& aDatastoreId);
|
||||
const uint32_t& aPrivateBrowsingId, const uint64_t& aDatastoreId,
|
||||
mozilla::ipc::Endpoint<PBackgroundLSDatabaseParent>&& aParentEndpoint);
|
||||
|
||||
PBackgroundLSObserverParent* AllocPBackgroundLSObserverParent(
|
||||
const uint64_t& aObserverId);
|
||||
|
||||
@@ -98,8 +98,8 @@ LSDatabase::~LSDatabase() {
|
||||
}
|
||||
|
||||
if (mActor) {
|
||||
mActor->SendDelete();
|
||||
MOZ_ASSERT(!mActor, "SendDelete should have cleared!");
|
||||
mActor->Shutdown();
|
||||
MOZ_ASSERT(!mActor, "Shutdown should have cleared!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -938,8 +938,16 @@ nsresult LSObject::EnsureDatabase() {
|
||||
|
||||
RefPtr<LSDatabaseChild> actor = new LSDatabaseChild(database);
|
||||
|
||||
MOZ_ALWAYS_TRUE(backgroundActor->SendPBackgroundLSDatabaseConstructor(
|
||||
actor, *mStoragePrincipalInfo, mPrivateBrowsingId, datastoreId));
|
||||
mozilla::ipc::Endpoint<PBackgroundLSDatabaseParent> parentEndpoint;
|
||||
mozilla::ipc::Endpoint<PBackgroundLSDatabaseChild> childEndpoint;
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
PBackgroundLSDatabase::CreateEndpoints(&parentEndpoint, &childEndpoint));
|
||||
|
||||
MOZ_ALWAYS_TRUE(childEndpoint.Bind(actor));
|
||||
|
||||
MOZ_ALWAYS_TRUE(backgroundActor->SendCreateBackgroundLSDatabaseParent(
|
||||
*mStoragePrincipalInfo, mPrivateBrowsingId, datastoreId,
|
||||
std::move(parentEndpoint)));
|
||||
|
||||
database->SetActor(actor);
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
include protocol PBackgroundLSSnapshot;
|
||||
|
||||
include PBackgroundLSSharedTypes;
|
||||
@@ -92,10 +91,9 @@ struct LSSnapshotInitInfo
|
||||
* ContentParent::AboutToLoadHttpDocumentForChild, the central place
|
||||
* for pre-loading.)
|
||||
*/
|
||||
[ChildImpl=virtual, ParentImpl=virtual]
|
||||
[ChildImpl=virtual, ParentImpl=virtual, ChildProc=anydom]
|
||||
sync protocol PBackgroundLSDatabase
|
||||
{
|
||||
manager PBackground;
|
||||
manages PBackgroundLSSnapshot;
|
||||
|
||||
parent:
|
||||
@@ -153,9 +151,6 @@ child:
|
||||
* ContentParent::ShutDownProcess.
|
||||
*/
|
||||
async RequestAllowToClose();
|
||||
|
||||
both:
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -274,29 +274,20 @@ BackgroundParentImpl::RecvPBackgroundSDBConnectionConstructor(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
already_AddRefed<BackgroundParentImpl::PBackgroundLSDatabaseParent>
|
||||
BackgroundParentImpl::AllocPBackgroundLSDatabaseParent(
|
||||
const PrincipalInfo& aPrincipalInfo, const uint32_t& aPrivateBrowsingId,
|
||||
const uint64_t& aDatastoreId) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
return mozilla::dom::AllocPBackgroundLSDatabaseParent(
|
||||
aPrincipalInfo, aPrivateBrowsingId, aDatastoreId);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
BackgroundParentImpl::RecvPBackgroundLSDatabaseConstructor(
|
||||
PBackgroundLSDatabaseParent* aActor, const PrincipalInfo& aPrincipalInfo,
|
||||
const uint32_t& aPrivateBrowsingId, const uint64_t& aDatastoreId) {
|
||||
BackgroundParentImpl::RecvCreateBackgroundLSDatabaseParent(
|
||||
const PrincipalInfo& aPrincipalInfo, const uint32_t& aPrivateBrowsingId,
|
||||
const uint64_t& aDatastoreId,
|
||||
Endpoint<PBackgroundLSDatabaseParent>&& aParentEndpoint) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
if (!mozilla::dom::RecvPBackgroundLSDatabaseConstructor(
|
||||
aActor, aPrincipalInfo, aPrivateBrowsingId, aDatastoreId)) {
|
||||
if (!mozilla::dom::RecvCreateBackgroundLSDatabaseParent(
|
||||
aPrincipalInfo, aPrivateBrowsingId, aDatastoreId,
|
||||
std::move(aParentEndpoint))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
||||
@@ -56,15 +56,10 @@ class BackgroundParentImpl : public PBackgroundParent {
|
||||
const PersistenceType& aPersistenceType,
|
||||
const PrincipalInfo& aPrincipalInfo) override;
|
||||
|
||||
already_AddRefed<PBackgroundLSDatabaseParent>
|
||||
AllocPBackgroundLSDatabaseParent(const PrincipalInfo& aPrincipalInfo,
|
||||
const uint32_t& aPrivateBrowsingId,
|
||||
const uint64_t& aDatastoreId) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvPBackgroundLSDatabaseConstructor(
|
||||
PBackgroundLSDatabaseParent* aActor, const PrincipalInfo& aPrincipalInfo,
|
||||
const uint32_t& aPrivateBrowsingId,
|
||||
const uint64_t& aDatastoreId) override;
|
||||
mozilla::ipc::IPCResult RecvCreateBackgroundLSDatabaseParent(
|
||||
const PrincipalInfo& aPrincipalInfo, const uint32_t& aPrivateBrowsingId,
|
||||
const uint64_t& aDatastoreId,
|
||||
Endpoint<PBackgroundLSDatabaseParent>&& aParentEndpoint) override;
|
||||
|
||||
PBackgroundLSObserverParent* AllocPBackgroundLSObserverParent(
|
||||
const uint64_t& aObserverId) override;
|
||||
|
||||
@@ -86,7 +86,6 @@ sync protocol PBackground
|
||||
manages PBackgroundIDBFactory;
|
||||
manages PBackgroundIndexedDBUtils;
|
||||
manages PBackgroundSDBConnection;
|
||||
manages PBackgroundLSDatabase;
|
||||
manages PBackgroundLSObserver;
|
||||
manages PBackgroundLSRequest;
|
||||
manages PBackgroundLSSimpleRequest;
|
||||
@@ -139,9 +138,11 @@ parent:
|
||||
async PBackgroundSDBConnection(PersistenceType persistenceType,
|
||||
PrincipalInfo principalInfo);
|
||||
|
||||
async PBackgroundLSDatabase(PrincipalInfo principalInfo,
|
||||
uint32_t privateBrowsingId,
|
||||
uint64_t datastoreId);
|
||||
async CreateBackgroundLSDatabaseParent(
|
||||
PrincipalInfo principalInfo,
|
||||
uint32_t privateBrowsingId,
|
||||
uint64_t datastoreId,
|
||||
Endpoint<PBackgroundLSDatabaseParent> aParentEndpoint);
|
||||
|
||||
async PBackgroundLSObserver(uint64_t observerId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user