mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1215723 - Part 2: Initialize DataStorage items in the content process from the data in the parent; r=keeler
This commit is contained in:
parent
ef691b31b2
commit
3990e391f4
@ -35,6 +35,7 @@
|
||||
#include "imgIContainer.h"
|
||||
#include "mozIApplication.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/DataStorage.h"
|
||||
#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
|
||||
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
||||
#include "mozilla/dom/DataStoreService.h"
|
||||
@ -2672,6 +2673,15 @@ ContentParent::RecvReadFontList(InfallibleTArray<FontListEntry>* retValue)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvReadDataStorageArray(const nsString& aFilename,
|
||||
InfallibleTArray<DataStorageItem>* aValues)
|
||||
{
|
||||
RefPtr<DataStorage> storage = DataStorage::Get(aFilename);
|
||||
storage->GetAll(aValues);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions)
|
||||
{
|
||||
|
@ -743,6 +743,9 @@ private:
|
||||
virtual bool RecvReadPrefsArray(InfallibleTArray<PrefSetting>* aPrefs) override;
|
||||
virtual bool RecvReadFontList(InfallibleTArray<FontListEntry>* retValue) override;
|
||||
|
||||
virtual bool RecvReadDataStorageArray(const nsString& aFilename,
|
||||
InfallibleTArray<DataStorageItem>* aValues) override;
|
||||
|
||||
virtual bool RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions) override;
|
||||
|
||||
virtual bool RecvSetClipboard(const IPCDataTransfer& aDataTransfer,
|
||||
|
@ -91,6 +91,7 @@ using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
|
||||
using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h";
|
||||
using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h";
|
||||
using class mozilla::dom::ipc::StructuredCloneData from "ipc/IPCMessageUtils.h";
|
||||
using mozilla::DataStorageType from "ipc/DataStorageIPCUtils.h";
|
||||
|
||||
union ChromeRegistryItem
|
||||
{
|
||||
@ -324,6 +325,12 @@ struct PrefSetting {
|
||||
MaybePrefValue userValue;
|
||||
};
|
||||
|
||||
struct DataStorageItem {
|
||||
nsCString key;
|
||||
nsCString value;
|
||||
DataStorageType type;
|
||||
};
|
||||
|
||||
struct DataStoreSetting {
|
||||
nsString name;
|
||||
nsString originURL;
|
||||
@ -839,6 +846,9 @@ 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);
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include "DataStorage.h"
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/PContent.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
@ -42,6 +44,7 @@ DataStorage::DataStorage(const nsString& aFilename)
|
||||
: mMutex("DataStorage::mMutex")
|
||||
, mPendingWrite(false)
|
||||
, mShuttingDown(false)
|
||||
, mInitCalled(false)
|
||||
, mReadyMonitor("DataStorage::mReadyMonitor")
|
||||
, mReady(false)
|
||||
, mFilename(aFilename)
|
||||
@ -80,15 +83,41 @@ DataStorage::Init(bool& aDataWillPersist)
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
nsresult rv;
|
||||
rv = NS_NewThread(getter_AddRefs(mWorkerThread));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
// Ignore attempts to initialize several times.
|
||||
if (mInitCalled) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = AsyncReadData(aDataWillPersist, lock);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
mInitCalled = true;
|
||||
|
||||
nsresult rv;
|
||||
if (XRE_IsParentProcess()) {
|
||||
rv = NS_NewThread(getter_AddRefs(mWorkerThread));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = AsyncReadData(aDataWillPersist, lock);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
// In the child process, we ask the parent process for the data.
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
aDataWillPersist = false;
|
||||
InfallibleTArray<DataStorageItem> items;
|
||||
dom::ContentChild::GetSingleton()->
|
||||
SendReadDataStorageArray(mFilename, &items);
|
||||
for (auto& item : items) {
|
||||
Entry entry;
|
||||
entry.mValue = item.value();
|
||||
rv = PutInternal(item.key(), entry, item.type(), lock);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
mReady = true;
|
||||
NotifyObservers("data-storage-ready");
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
@ -337,6 +366,7 @@ nsresult
|
||||
DataStorage::AsyncReadData(bool& aHaveProfileDir,
|
||||
const MutexAutoLock& /*aProofOfLock*/)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
aHaveProfileDir = false;
|
||||
// Allocate a Reader so that even if it isn't dispatched,
|
||||
// the data-storage-ready notification will be fired and Get
|
||||
@ -425,6 +455,34 @@ DataStorage::GetTableForType(DataStorageType aType,
|
||||
MOZ_CRASH("given bad DataStorage storage type");
|
||||
}
|
||||
|
||||
void
|
||||
DataStorage::ReadAllFromTable(DataStorageType aType,
|
||||
InfallibleTArray<dom::DataStorageItem>* aItems,
|
||||
const MutexAutoLock& aProofOfLock)
|
||||
{
|
||||
for (auto iter = GetTableForType(aType, aProofOfLock).Iter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
DataStorageItem* item = aItems->AppendElement();
|
||||
item->key() = iter.Key();
|
||||
item->value() = iter.Data().mValue;
|
||||
item->type() = aType;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DataStorage::GetAll(InfallibleTArray<dom::DataStorageItem>* aItems)
|
||||
{
|
||||
WaitForReady();
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
aItems->SetCapacity(mPersistentDataTable.Count() +
|
||||
mTemporaryDataTable.Count() +
|
||||
mPrivateDataTable.Count());
|
||||
ReadAllFromTable(DataStorage_Persistent, aItems, lock);
|
||||
ReadAllFromTable(DataStorage_Temporary, aItems, lock);
|
||||
ReadAllFromTable(DataStorage_Private, aItems, lock);
|
||||
}
|
||||
|
||||
// Limit the number of entries per table. This is to prevent unbounded
|
||||
// resource use. The eviction strategy is as follows:
|
||||
// - An entry's score is incremented once for every day it is accessed.
|
||||
@ -591,6 +649,8 @@ DataStorage::Writer::Run()
|
||||
nsresult
|
||||
DataStorage::AsyncWriteData(const MutexAutoLock& /*aProofOfLock*/)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
if (mShuttingDown || !mBackingFile) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -627,12 +687,14 @@ DataStorage::Clear()
|
||||
mTemporaryDataTable.Clear();
|
||||
mPrivateDataTable.Clear();
|
||||
|
||||
// Asynchronously clear the file. This is similar to the permission manager
|
||||
// in that it doesn't wait to synchronously remove the data from its backing
|
||||
// storage either.
|
||||
nsresult rv = AsyncWriteData(lock);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (XRE_IsParentProcess()) {
|
||||
// Asynchronously clear the file. This is similar to the permission manager
|
||||
// in that it doesn't wait to synchronously remove the data from its backing
|
||||
// storage either.
|
||||
nsresult rv = AsyncWriteData(lock);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -641,6 +703,8 @@ DataStorage::Clear()
|
||||
void
|
||||
DataStorage::TimerCallback(nsITimer* aTimer, void* aClosure)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
RefPtr<DataStorage> aDataStorage = (DataStorage*)aClosure;
|
||||
MutexAutoLock lock(aDataStorage->mMutex);
|
||||
Unused << aDataStorage->AsyncWriteData(lock);
|
||||
@ -651,7 +715,7 @@ DataStorage::TimerCallback(nsITimer* aTimer, void* aClosure)
|
||||
nsresult
|
||||
DataStorage::AsyncSetTimer(const MutexAutoLock& /*aProofOfLock*/)
|
||||
{
|
||||
if (mShuttingDown) {
|
||||
if (mShuttingDown || !XRE_IsParentProcess()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -669,6 +733,8 @@ void
|
||||
DataStorage::SetTimer()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
nsresult rv;
|
||||
@ -702,6 +768,8 @@ DataStorage::NotifyObservers(const char* aTopic)
|
||||
nsresult
|
||||
DataStorage::DispatchShutdownTimer(const MutexAutoLock& /*aProofOfLock*/)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
nsCOMPtr<nsIRunnable> job =
|
||||
NS_NewRunnableMethod(this, &DataStorage::ShutdownTimer);
|
||||
nsresult rv = mWorkerThread->Dispatch(job, NS_DISPATCH_NORMAL);
|
||||
@ -714,6 +782,7 @@ DataStorage::DispatchShutdownTimer(const MutexAutoLock& /*aProofOfLock*/)
|
||||
void
|
||||
DataStorage::ShutdownTimer()
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MutexAutoLock lock(mMutex);
|
||||
nsresult rv = mTimer->Cancel();
|
||||
@ -740,22 +809,24 @@ DataStorage::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
MutexAutoLock lock(mMutex);
|
||||
mPrivateDataTable.Clear();
|
||||
} else if (strcmp(aTopic, "profile-before-change") == 0) {
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
rv = AsyncWriteData(lock);
|
||||
mShuttingDown = true;
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
if (mTimer) {
|
||||
rv = DispatchShutdownTimer(lock);
|
||||
if (XRE_IsParentProcess()) {
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
rv = AsyncWriteData(lock);
|
||||
mShuttingDown = true;
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
if (mTimer) {
|
||||
rv = DispatchShutdownTimer(lock);
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
}
|
||||
// Run the thread to completion and prevent any further events
|
||||
// being scheduled to it. The thread may need the lock, so we can't
|
||||
// hold it here.
|
||||
rv = mWorkerThread->Shutdown();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
// Run the thread to completion and prevent any further events
|
||||
// being scheduled to it. The thread may need the lock, so we can't
|
||||
// hold it here.
|
||||
rv = mWorkerThread->Shutdown();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
sDataStorages->Clear();
|
||||
|
@ -20,6 +20,10 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class DataStorageItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* DataStorage is a threadsafe, generic, narrow string-based hash map that
|
||||
* persists data on disk and additionally handles temporary and private data.
|
||||
@ -83,6 +87,8 @@ enum DataStorageType {
|
||||
|
||||
class DataStorage : public nsIObserver
|
||||
{
|
||||
typedef dom::DataStorageItem DataStorageItem;
|
||||
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
@ -109,6 +115,9 @@ public:
|
||||
// Removes all entries of all types of data.
|
||||
nsresult Clear();
|
||||
|
||||
// Read all of the data items.
|
||||
void GetAll(InfallibleTArray<DataStorageItem>* aItems);
|
||||
|
||||
private:
|
||||
explicit DataStorage(const nsString& aFilename);
|
||||
virtual ~DataStorage();
|
||||
@ -162,6 +171,10 @@ private:
|
||||
DataStorageTable& GetTableForType(DataStorageType aType,
|
||||
const MutexAutoLock& aProofOfLock);
|
||||
|
||||
void ReadAllFromTable(DataStorageType aType,
|
||||
InfallibleTArray<DataStorageItem>* aItems,
|
||||
const MutexAutoLock& aProofOfLock);
|
||||
|
||||
Mutex mMutex; // This mutex protects access to the following members:
|
||||
DataStorageTable mPersistentDataTable;
|
||||
DataStorageTable mTemporaryDataTable;
|
||||
@ -172,6 +185,7 @@ private:
|
||||
uint32_t mTimerDelay; // in milliseconds
|
||||
bool mPendingWrite; // true if a write is needed but hasn't been dispatched
|
||||
bool mShuttingDown;
|
||||
bool mInitCalled; // Indicates that Init() has been called.
|
||||
// (End list of members protected by mMutex)
|
||||
|
||||
Monitor mReadyMonitor; // Do not acquire this at the same time as mMutex.
|
||||
|
21
security/manager/ssl/DataStorageIPCUtils.h
Normal file
21
security/manager/ssl/DataStorageIPCUtils.h
Normal file
@ -0,0 +1,21 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
#ifndef ipc_DataStorageIPCUtils_h
|
||||
#define ipc_DataStorageIPCUtils_h
|
||||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "mozilla/DataStorage.h"
|
||||
|
||||
namespace IPC {
|
||||
template<>
|
||||
struct ParamTraits<mozilla::DataStorageType> :
|
||||
public ContiguousEnumSerializer<mozilla::DataStorageType,
|
||||
mozilla::DataStorage_Persistent,
|
||||
mozilla::DataStorageType(mozilla::DataStorage_Private + 1)> {};
|
||||
} // namespace IPC
|
||||
|
||||
#endif // mozilla_DataStorageIPCUtils_hh
|
@ -75,6 +75,10 @@ EXPORTS.mozilla.psm += [
|
||||
'PSMContentListener.h',
|
||||
]
|
||||
|
||||
EXPORTS.ipc += [
|
||||
'DataStorageIPCUtils.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'CertBlocklist.cpp',
|
||||
'CryptoTask.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user