Bug 1343731 - Remove the sync IPC during DataStorage initialization; r=keeler,billm

Instead of initializing DataStorage objects on demand in the content
process, we initialize them at content process startup by getting the
parent to send down the information about the existing DataStorages at
child process startup.  After that point, the dynamic change
notifications added in bug 1215723 will take care of keeping the
information in sync.
This commit is contained in:
Ehsan Akhgari 2017-02-25 11:14:04 -05:00
Родитель 5ab5fb52c4
Коммит e559e3333d
7 изменённых файлов: 70 добавлений и 33 удалений

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

@ -1028,6 +1028,8 @@ ContentChild::InitXPCOM(const XPCOMInitData& aXPCOMInit,
mozilla::dom::time::InitializeDateCacheCleaner();
GfxInfoBase::SetFeatureStatus(aXPCOMInit.gfxFeatureStatus());
DataStorage::SetCachedStorageEntries(aXPCOMInit.dataStorage());
}
mozilla::ipc::IPCResult

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

@ -2203,6 +2203,19 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
}
}
// Ensure the SSS is initialized before we try to use its storage.
nsCOMPtr<nsISiteSecurityService> sss = do_GetService("@mozilla.org/ssservice;1");
nsTArray<nsString> storageFiles;
DataStorage::GetAllFileNames(storageFiles);
for (auto& file : storageFiles) {
dom::DataStorageEntry entry;
entry.filename() = file;
RefPtr<DataStorage> storage = DataStorage::Get(file);
storage->GetAll(&entry.items());
xpcomInit.dataStorage().AppendElement(Move(entry));
}
Unused << SendSetXPCOMProcessAttributes(xpcomInit, initialData, lnfCache);
if (aSendRegisteredChrome) {
@ -2440,24 +2453,6 @@ ContentParent::RecvReadFontList(InfallibleTArray<FontListEntry>* retValue)
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvReadDataStorageArray(const nsString& aFilename,
InfallibleTArray<DataStorageItem>* aValues)
{
// If we're shutting down, the DataStorage object may have been cleared
// already, and setting it up is pointless anyways since we're about to die.
if (mShutdownPending) {
return IPC_OK();
}
// Ensure the SSS is initialized before we try to use its storage.
nsCOMPtr<nsISiteSecurityService> sss = do_GetService("@mozilla.org/ssservice;1");
RefPtr<DataStorage> storage = DataStorage::Get(aFilename);
storage->GetAll(aValues);
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions)
{

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

@ -898,9 +898,6 @@ private:
virtual mozilla::ipc::IPCResult RecvReadFontList(InfallibleTArray<FontListEntry>* retValue) override;
virtual mozilla::ipc::IPCResult RecvReadDataStorageArray(const nsString& aFilename,
InfallibleTArray<DataStorageItem>* aValues) override;
virtual mozilla::ipc::IPCResult RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions) override;
virtual mozilla::ipc::IPCResult RecvSetClipboard(const IPCDataTransfer& aDataTransfer,

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

@ -146,6 +146,11 @@ struct DataStorageItem {
DataStorageType type;
};
struct DataStorageEntry {
DataStorageItem[] items;
nsString filename;
};
struct ClipboardCapabilities {
bool supportsSelectionClipboard;
bool supportsFindClipboard;
@ -257,6 +262,7 @@ struct XPCOMInitData
OptionalURIParams userContentSheetURL;
PrefSetting[] prefs;
GfxInfoFeatureStatus[] gfxFeatureStatus;
DataStorageEntry[] dataStorage;
};
/**
@ -732,9 +738,6 @@ parent:
sync ReadFontList() returns (FontListEntry[] retValue);
sync ReadDataStorageArray(nsString aFilename)
returns (DataStorageItem[] retValue);
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal)
returns (StructuredCloneData[] retval);

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

@ -774,8 +774,6 @@ description =
description =
[PContent::ReadFontList]
description =
[PContent::ReadDataStorageArray]
description =
[PContent::ReadPermissions]
description =
[PContent::GetClipboard]

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

@ -86,8 +86,36 @@ DataStorage::GetIfExists(const nsString& aFilename)
return storage.forget();
}
// static
void
DataStorage::GetAllFileNames(nsTArray<nsString>& aItems)
{
MOZ_ASSERT(NS_IsMainThread());
if (!sDataStorages) {
return;
}
for (auto iter = sDataStorages->Iter(); !iter.Done(); iter.Next()) {
aItems.AppendElement(iter.Key());
}
}
// static
void
DataStorage::SetCachedStorageEntries(
const InfallibleTArray<mozilla::dom::DataStorageEntry>& aEntries)
{
MOZ_ASSERT(XRE_IsContentProcess());
for (auto& entry : aEntries) {
RefPtr<DataStorage> storage = DataStorage::Get(entry.filename());
bool dataWillPersist = false;
storage->Init(dataWillPersist, &entry.items());
}
}
nsresult
DataStorage::Init(bool& aDataWillPersist)
DataStorage::Init(bool& aDataWillPersist,
const InfallibleTArray<mozilla::dom::DataStorageItem>* aItems)
{
// Don't access the observer service or preferences off the main thread.
if (!NS_IsMainThread()) {
@ -106,6 +134,8 @@ DataStorage::Init(bool& aDataWillPersist)
nsresult rv;
if (XRE_IsParentProcess()) {
MOZ_ASSERT(!aItems);
rv = NS_NewNamedThread("DataStorage", getter_AddRefs(mWorkerThread));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -116,13 +146,13 @@ DataStorage::Init(bool& aDataWillPersist)
return rv;
}
} else {
// In the child process, we ask the parent process for the data.
// In the child process, we use the data passed to us by the parent process
// to initialize.
MOZ_ASSERT(XRE_IsContentProcess());
MOZ_ASSERT(aItems);
aDataWillPersist = false;
InfallibleTArray<DataStorageItem> items;
dom::ContentChild::GetSingleton()->
SendReadDataStorageArray(mFilename, &items);
for (auto& item : items) {
for (auto& item : *aItems) {
Entry entry;
entry.mValue = item.value();
rv = PutInternal(item.key(), entry, item.type(), lock);

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

@ -22,6 +22,7 @@
namespace mozilla {
namespace dom {
class DataStorageEntry;
class DataStorageItem;
}
@ -101,7 +102,12 @@ public:
// Initializes the DataStorage. Must be called before using.
// aDataWillPersist returns whether or not data can be persistently saved.
nsresult Init(/*out*/bool& aDataWillPersist);
// aItems is used in the content process to initialize a cache of the items
// received from the parent process over IPC. nullptr must be passed for the
// parent process.
nsresult Init(/*out*/bool& aDataWillPersist,
const InfallibleTArray<mozilla::dom::DataStorageItem>*
aItems = nullptr);
// Given a key and a type of data, returns a value. Returns an empty string if
// the key is not present for that type of data. If Get is called before the
// "data-storage-ready" event is observed, it will block. NB: It is not
@ -117,9 +123,15 @@ public:
// Removes all entries of all types of data.
nsresult Clear();
// Read all file names that we know about.
static void GetAllFileNames(nsTArray<nsString>& aItems);
// Read all of the data items.
void GetAll(InfallibleTArray<DataStorageItem>* aItems);
// Set the cached copy of our DataStorage entries in the content process.
static void SetCachedStorageEntries(const InfallibleTArray<mozilla::dom::DataStorageEntry>& aEntries);
private:
explicit DataStorage(const nsString& aFilename);
virtual ~DataStorage();