Bug 1454816 - Replace uses of base::SharedMemory r=ipc-reviewers,media-playback-reviewers,padenot,nika
Differential Revision: https://phabricator.services.mozilla.com/D224153
This commit is contained in:
@@ -2388,7 +2388,7 @@ mozilla::ipc::IPCResult ContentChild::RecvRegisterStringBundles(
|
|||||||
|
|
||||||
for (auto& descriptor : aDescriptors) {
|
for (auto& descriptor : aDescriptors) {
|
||||||
stringBundleService->RegisterContentBundle(
|
stringBundleService->RegisterContentBundle(
|
||||||
descriptor.bundleURL(), descriptor.mapFile(), descriptor.mapSize());
|
descriptor.bundleURL(), descriptor.mapHandle(), descriptor.mapSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
@@ -2401,7 +2401,7 @@ mozilla::ipc::IPCResult ContentChild::RecvUpdateL10nFileSources(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mozilla::ipc::IPCResult ContentChild::RecvUpdateSharedData(
|
mozilla::ipc::IPCResult ContentChild::RecvUpdateSharedData(
|
||||||
const FileDescriptor& aMapFile, const uint32_t& aMapSize,
|
SharedMemoryHandle&& aMapHandle, const uint32_t& aMapSize,
|
||||||
nsTArray<IPCBlob>&& aBlobs, nsTArray<nsCString>&& aChangedKeys) {
|
nsTArray<IPCBlob>&& aBlobs, nsTArray<nsCString>&& aChangedKeys) {
|
||||||
nsTArray<RefPtr<BlobImpl>> blobImpls(aBlobs.Length());
|
nsTArray<RefPtr<BlobImpl>> blobImpls(aBlobs.Length());
|
||||||
for (auto& ipcBlob : aBlobs) {
|
for (auto& ipcBlob : aBlobs) {
|
||||||
@@ -2409,12 +2409,12 @@ mozilla::ipc::IPCResult ContentChild::RecvUpdateSharedData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mSharedData) {
|
if (mSharedData) {
|
||||||
mSharedData->Update(aMapFile, aMapSize, std::move(blobImpls),
|
mSharedData->Update(std::move(aMapHandle), aMapSize, std::move(blobImpls),
|
||||||
std::move(aChangedKeys));
|
std::move(aChangedKeys));
|
||||||
} else {
|
} else {
|
||||||
mSharedData =
|
mSharedData =
|
||||||
new SharedMap(ContentProcessMessageManager::Get()->GetParentObject(),
|
new SharedMap(ContentProcessMessageManager::Get()->GetParentObject(),
|
||||||
aMapFile, aMapSize, std::move(blobImpls));
|
std::move(aMapHandle), aMapSize, std::move(blobImpls));
|
||||||
}
|
}
|
||||||
|
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
@@ -2482,7 +2482,7 @@ mozilla::ipc::IPCResult ContentChild::RecvRebuildFontList(
|
|||||||
|
|
||||||
mozilla::ipc::IPCResult ContentChild::RecvFontListShmBlockAdded(
|
mozilla::ipc::IPCResult ContentChild::RecvFontListShmBlockAdded(
|
||||||
const uint32_t& aGeneration, const uint32_t& aIndex,
|
const uint32_t& aGeneration, const uint32_t& aIndex,
|
||||||
base::SharedMemoryHandle&& aHandle) {
|
SharedMemoryHandle&& aHandle) {
|
||||||
if (gfxPlatform::Initialized()) {
|
if (gfxPlatform::Initialized()) {
|
||||||
gfxPlatformFontList::PlatformFontList()->ShmBlockAdded(aGeneration, aIndex,
|
gfxPlatformFontList::PlatformFontList()->ShmBlockAdded(aGeneration, aIndex,
|
||||||
std::move(aHandle));
|
std::move(aHandle));
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ class ContentChild final : public PContentChild,
|
|||||||
const mozilla::dom::ipc::StructuredCloneData& aInitialData,
|
const mozilla::dom::ipc::StructuredCloneData& aInitialData,
|
||||||
bool aIsReadyForBackgroundProcessing);
|
bool aIsReadyForBackgroundProcessing);
|
||||||
|
|
||||||
void InitSharedUASheets(Maybe<base::SharedMemoryHandle>&& aHandle,
|
void InitSharedUASheets(Maybe<SharedMemoryHandle>&& aHandle,
|
||||||
uintptr_t aAddress);
|
uintptr_t aAddress);
|
||||||
|
|
||||||
void InitGraphicsDeviceData(const ContentDeviceData& aData);
|
void InitGraphicsDeviceData(const ContentDeviceData& aData);
|
||||||
@@ -314,7 +314,7 @@ class ContentChild final : public PContentChild,
|
|||||||
nsTArray<L10nFileSourceDescriptor>&& aDescriptors);
|
nsTArray<L10nFileSourceDescriptor>&& aDescriptors);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvUpdateSharedData(
|
mozilla::ipc::IPCResult RecvUpdateSharedData(
|
||||||
const FileDescriptor& aMapFile, const uint32_t& aMapSize,
|
SharedMemoryHandle&& aMapHandle, const uint32_t& aMapSize,
|
||||||
nsTArray<IPCBlob>&& aBlobs, nsTArray<nsCString>&& aChangedKeys);
|
nsTArray<IPCBlob>&& aBlobs, nsTArray<nsCString>&& aChangedKeys);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvFontListChanged();
|
mozilla::ipc::IPCResult RecvFontListChanged();
|
||||||
@@ -334,7 +334,7 @@ class ContentChild final : public PContentChild,
|
|||||||
mozilla::ipc::IPCResult RecvRebuildFontList(const bool& aFullRebuild);
|
mozilla::ipc::IPCResult RecvRebuildFontList(const bool& aFullRebuild);
|
||||||
mozilla::ipc::IPCResult RecvFontListShmBlockAdded(
|
mozilla::ipc::IPCResult RecvFontListShmBlockAdded(
|
||||||
const uint32_t& aGeneration, const uint32_t& aIndex,
|
const uint32_t& aGeneration, const uint32_t& aIndex,
|
||||||
base::SharedMemoryHandle&& aHandle);
|
SharedMemoryHandle&& aHandle);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvUpdateAppLocales(
|
mozilla::ipc::IPCResult RecvUpdateAppLocales(
|
||||||
nsTArray<nsCString>&& aAppLocales);
|
nsTArray<nsCString>&& aAppLocales);
|
||||||
@@ -510,9 +510,9 @@ class ContentChild final : public PContentChild,
|
|||||||
mozilla::ipc::IPCResult RecvSetXPCOMProcessAttributes(
|
mozilla::ipc::IPCResult RecvSetXPCOMProcessAttributes(
|
||||||
XPCOMInitData&& aXPCOMInit, const StructuredCloneData& aInitialData,
|
XPCOMInitData&& aXPCOMInit, const StructuredCloneData& aInitialData,
|
||||||
FullLookAndFeel&& aLookAndFeelData, SystemFontList&& aFontList,
|
FullLookAndFeel&& aLookAndFeelData, SystemFontList&& aFontList,
|
||||||
Maybe<base::SharedMemoryHandle>&& aSharedUASheetHandle,
|
Maybe<SharedMemoryHandle>&& aSharedUASheetHandle,
|
||||||
const uintptr_t& aSharedUASheetAddress,
|
const uintptr_t& aSharedUASheetAddress,
|
||||||
nsTArray<base::SharedMemoryHandle>&& aSharedFontListBlocks,
|
nsTArray<SharedMemoryHandle>&& aSharedFontListBlocks,
|
||||||
const bool& aIsReadyForBackgroundProcessing);
|
const bool& aIsReadyForBackgroundProcessing);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvProvideAnonymousTemporaryFile(
|
mozilla::ipc::IPCResult RecvProvideAnonymousTemporaryFile(
|
||||||
@@ -542,7 +542,7 @@ class ContentChild final : public PContentChild,
|
|||||||
// for use during gfx initialization.
|
// for use during gfx initialization.
|
||||||
SystemFontList& SystemFontList() { return mFontList; }
|
SystemFontList& SystemFontList() { return mFontList; }
|
||||||
|
|
||||||
nsTArray<base::SharedMemoryHandle>& SharedFontListBlocks() {
|
nsTArray<SharedMemoryHandle>& SharedFontListBlocks() {
|
||||||
return mSharedFontListBlocks;
|
return mSharedFontListBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -831,7 +831,7 @@ class ContentChild final : public PContentChild,
|
|||||||
// Temporary storage for look and feel data.
|
// Temporary storage for look and feel data.
|
||||||
FullLookAndFeel mLookAndFeelData;
|
FullLookAndFeel mLookAndFeelData;
|
||||||
// Temporary storage for list of shared-fontlist memory blocks.
|
// Temporary storage for list of shared-fontlist memory blocks.
|
||||||
nsTArray<base::SharedMemoryHandle> mSharedFontListBlocks;
|
nsTArray<SharedMemoryHandle> mSharedFontListBlocks;
|
||||||
|
|
||||||
AppInfo mAppInfo;
|
AppInfo mAppInfo;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
|
|
||||||
#include "base/basictypes.h"
|
#include "base/basictypes.h"
|
||||||
#include "base/shared_memory.h"
|
|
||||||
|
|
||||||
#include "ContentParent.h"
|
#include "ContentParent.h"
|
||||||
#include "mozilla/ipc/ProcessUtils.h"
|
#include "mozilla/ipc/ProcessUtils.h"
|
||||||
@@ -151,6 +150,7 @@
|
|||||||
#include "mozilla/ipc/Endpoint.h"
|
#include "mozilla/ipc/Endpoint.h"
|
||||||
#include "mozilla/ipc/FileDescriptorUtils.h"
|
#include "mozilla/ipc/FileDescriptorUtils.h"
|
||||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "mozilla/ipc/TestShellParent.h"
|
#include "mozilla/ipc/TestShellParent.h"
|
||||||
#include "mozilla/layers/CompositorThread.h"
|
#include "mozilla/layers/CompositorThread.h"
|
||||||
#include "mozilla/layers/ImageBridgeParent.h"
|
#include "mozilla/layers/ImageBridgeParent.h"
|
||||||
@@ -1526,11 +1526,12 @@ void ContentParent::GetAllEvenIfDead(nsTArray<ContentParent*>& aArray) {
|
|||||||
|
|
||||||
void ContentParent::BroadcastStringBundle(
|
void ContentParent::BroadcastStringBundle(
|
||||||
const StringBundleDescriptor& aBundle) {
|
const StringBundleDescriptor& aBundle) {
|
||||||
AutoTArray<StringBundleDescriptor, 1> array;
|
|
||||||
array.AppendElement(aBundle);
|
|
||||||
|
|
||||||
for (auto* cp : AllProcesses(eLive)) {
|
for (auto* cp : AllProcesses(eLive)) {
|
||||||
Unused << cp->SendRegisterStringBundles(array);
|
AutoTArray<StringBundleDescriptor, 1> array;
|
||||||
|
array.AppendElement(StringBundleDescriptor(
|
||||||
|
aBundle.bundleURL(), SharedMemory::CloneHandle(aBundle.mapHandle()),
|
||||||
|
aBundle.mapSize()));
|
||||||
|
Unused << cp->SendRegisterStringBundles(std::move(array));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1544,9 +1545,9 @@ void ContentParent::BroadcastShmBlockAdded(uint32_t aGeneration,
|
|||||||
uint32_t aIndex) {
|
uint32_t aIndex) {
|
||||||
auto* pfl = gfxPlatformFontList::PlatformFontList();
|
auto* pfl = gfxPlatformFontList::PlatformFontList();
|
||||||
for (auto* cp : AllProcesses(eLive)) {
|
for (auto* cp : AllProcesses(eLive)) {
|
||||||
base::SharedMemoryHandle handle =
|
SharedMemory::Handle handle =
|
||||||
pfl->ShareShmBlockToProcess(aIndex, cp->Pid());
|
pfl->ShareShmBlockToProcess(aIndex, cp->Pid());
|
||||||
if (handle == base::SharedMemory::NULLHandle()) {
|
if (handle == SharedMemory::NULLHandle()) {
|
||||||
// If something went wrong here, we just skip it; the child will need to
|
// If something went wrong here, we just skip it; the child will need to
|
||||||
// request the block as needed, at some performance cost.
|
// request the block as needed, at some performance cost.
|
||||||
continue;
|
continue;
|
||||||
@@ -5680,7 +5681,7 @@ mozilla::ipc::IPCResult ContentParent::RecvShutdownPerfStats(
|
|||||||
|
|
||||||
mozilla::ipc::IPCResult ContentParent::RecvGetFontListShmBlock(
|
mozilla::ipc::IPCResult ContentParent::RecvGetFontListShmBlock(
|
||||||
const uint32_t& aGeneration, const uint32_t& aIndex,
|
const uint32_t& aGeneration, const uint32_t& aIndex,
|
||||||
base::SharedMemoryHandle* aOut) {
|
SharedMemory::Handle* aOut) {
|
||||||
auto* fontList = gfxPlatformFontList::PlatformFontList();
|
auto* fontList = gfxPlatformFontList::PlatformFontList();
|
||||||
MOZ_RELEASE_ASSERT(fontList, "gfxPlatformFontList not initialized?");
|
MOZ_RELEASE_ASSERT(fontList, "gfxPlatformFontList not initialized?");
|
||||||
fontList->ShareFontListShmBlockToProcess(aGeneration, aIndex, Pid(), aOut);
|
fontList->ShareFontListShmBlockToProcess(aGeneration, aIndex, Pid(), aOut);
|
||||||
@@ -5732,7 +5733,7 @@ mozilla::ipc::IPCResult ContentParent::RecvStartCmapLoading(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mozilla::ipc::IPCResult ContentParent::RecvGetHyphDict(
|
mozilla::ipc::IPCResult ContentParent::RecvGetHyphDict(
|
||||||
nsIURI* aURI, base::SharedMemoryHandle* aOutHandle, uint32_t* aOutSize) {
|
nsIURI* aURI, SharedMemory::Handle* aOutHandle, uint32_t* aOutSize) {
|
||||||
if (!aURI) {
|
if (!aURI) {
|
||||||
return IPC_FAIL(this, "aURI must not be null.");
|
return IPC_FAIL(this, "aURI must not be null.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "mozilla/ipc/BackgroundUtils.h"
|
#include "mozilla/ipc/BackgroundUtils.h"
|
||||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||||
#include "mozilla/ipc/InputStreamUtils.h"
|
#include "mozilla/ipc/InputStreamUtils.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/DataMutex.h"
|
#include "mozilla/DataMutex.h"
|
||||||
#include "mozilla/HalTypes.h"
|
#include "mozilla/HalTypes.h"
|
||||||
@@ -1127,7 +1128,7 @@ class ContentParent final : public PContentParent,
|
|||||||
|
|
||||||
mozilla::ipc::IPCResult RecvGetFontListShmBlock(
|
mozilla::ipc::IPCResult RecvGetFontListShmBlock(
|
||||||
const uint32_t& aGeneration, const uint32_t& aIndex,
|
const uint32_t& aGeneration, const uint32_t& aIndex,
|
||||||
base::SharedMemoryHandle* aOut);
|
mozilla::ipc::SharedMemory::Handle* aOut);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvInitializeFamily(const uint32_t& aGeneration,
|
mozilla::ipc::IPCResult RecvInitializeFamily(const uint32_t& aGeneration,
|
||||||
const uint32_t& aFamilyIndex,
|
const uint32_t& aFamilyIndex,
|
||||||
@@ -1150,9 +1151,9 @@ class ContentParent final : public PContentParent,
|
|||||||
mozilla::ipc::IPCResult RecvStartCmapLoading(const uint32_t& aGeneration,
|
mozilla::ipc::IPCResult RecvStartCmapLoading(const uint32_t& aGeneration,
|
||||||
const uint32_t& aStartIndex);
|
const uint32_t& aStartIndex);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvGetHyphDict(nsIURI* aURIParams,
|
mozilla::ipc::IPCResult RecvGetHyphDict(
|
||||||
base::SharedMemoryHandle* aOutHandle,
|
nsIURI* aURIParams, mozilla::ipc::SharedMemory::Handle* aOutHandle,
|
||||||
uint32_t* aOutSize);
|
uint32_t* aOutSize);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvNotifyBenchmarkResult(const nsAString& aCodecName,
|
mozilla::ipc::IPCResult RecvNotifyBenchmarkResult(const nsAString& aCodecName,
|
||||||
const uint32_t& aDecodeFPS);
|
const uint32_t& aDecodeFPS);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include "mozilla/ipc/IOThreadChild.h"
|
#include "mozilla/ipc/IOThreadChild.h"
|
||||||
|
|
||||||
#include "ContentProcess.h"
|
#include "ContentProcess.h"
|
||||||
#include "base/shared_memory.h"
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
|
||||||
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
|
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
|
||||||
@@ -78,7 +77,7 @@ void ContentProcess::InfallibleInit(int aArgc, char* aArgv[]) {
|
|||||||
geckoargs::sParentBuildID.Get(aArgc, aArgv);
|
geckoargs::sParentBuildID.Get(aArgc, aArgv);
|
||||||
|
|
||||||
// command line: -jsInitHandle handle -jsInitLen length
|
// command line: -jsInitHandle handle -jsInitLen length
|
||||||
Maybe<UniqueFileHandle> jsInitHandle =
|
Maybe<mozilla::ipc::SharedMemoryHandle> jsInitHandle =
|
||||||
geckoargs::sJsInitHandle.Get(aArgc, aArgv);
|
geckoargs::sJsInitHandle.Get(aArgc, aArgv);
|
||||||
Maybe<uint64_t> jsInitLen = geckoargs::sJsInitLen.Get(aArgc, aArgv);
|
Maybe<uint64_t> jsInitLen = geckoargs::sJsInitLen.Get(aArgc, aArgv);
|
||||||
|
|
||||||
|
|||||||
@@ -6,39 +6,40 @@
|
|||||||
|
|
||||||
#include "MemMapSnapshot.h"
|
#include "MemMapSnapshot.h"
|
||||||
|
|
||||||
#include "mozilla/AutoMemMap.h"
|
|
||||||
#include "mozilla/ResultExtensions.h"
|
#include "mozilla/ResultExtensions.h"
|
||||||
#include "mozilla/Try.h"
|
|
||||||
#include "mozilla/ipc/FileDescriptor.h"
|
|
||||||
|
|
||||||
namespace mozilla::ipc {
|
namespace mozilla::ipc {
|
||||||
|
|
||||||
Result<Ok, nsresult> MemMapSnapshot::Init(size_t aSize) {
|
Result<Ok, nsresult> MemMapSnapshot::Init(size_t aSize) {
|
||||||
MOZ_ASSERT(!mInitialized);
|
MOZ_ASSERT(!mMem);
|
||||||
|
|
||||||
if (NS_WARN_IF(!mMem.CreateFreezeable(aSize))) {
|
auto aMem = MakeRefPtr<SharedMemory>();
|
||||||
|
if (NS_WARN_IF(!aMem->CreateFreezable(aSize))) {
|
||||||
return Err(NS_ERROR_FAILURE);
|
return Err(NS_ERROR_FAILURE);
|
||||||
}
|
}
|
||||||
if (NS_WARN_IF(!mMem.Map(aSize))) {
|
if (NS_WARN_IF(!aMem->Map(aSize))) {
|
||||||
return Err(NS_ERROR_FAILURE);
|
return Err(NS_ERROR_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mInitialized = true;
|
mMem = std::move(aMem);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Ok, nsresult> MemMapSnapshot::Finalize(loader::AutoMemMap& aMem) {
|
Result<Ok, nsresult> MemMapSnapshot::Finalize(RefPtr<SharedMemory>& aMem) {
|
||||||
MOZ_ASSERT(mInitialized);
|
MOZ_ASSERT(mMem);
|
||||||
|
|
||||||
if (NS_WARN_IF(!mMem.Freeze())) {
|
auto size = mMem->Size();
|
||||||
|
if (NS_WARN_IF(!mMem->Freeze())) {
|
||||||
|
return Err(NS_ERROR_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
aMem = std::move(mMem);
|
||||||
|
|
||||||
|
// We need to re-map the memory as `Freeze()` unmaps it.
|
||||||
|
if (NS_WARN_IF(!aMem->Map(size))) {
|
||||||
return Err(NS_ERROR_FAILURE);
|
return Err(NS_ERROR_FAILURE);
|
||||||
}
|
}
|
||||||
// TakeHandle resets mMem, so call max_size first.
|
|
||||||
size_t size = mMem.max_size();
|
|
||||||
FileDescriptor memHandle(mMem.TakeHandle());
|
|
||||||
MOZ_TRY(aMem.initWithHandle(memHandle, size));
|
|
||||||
|
|
||||||
mInitialized = false;
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,17 +9,13 @@
|
|||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/RangedPtr.h"
|
#include "mozilla/RangedPtr.h"
|
||||||
#include "mozilla/Result.h"
|
#include "mozilla/Result.h"
|
||||||
#include "base/shared_memory.h"
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "ErrorList.h"
|
#include "ErrorList.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla::ipc {
|
||||||
namespace loader {
|
|
||||||
class AutoMemMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ipc {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper class for creating a read-only snapshot of memory-mapped data.
|
* A helper class for creating a read-only snapshot of memory-mapped data.
|
||||||
@@ -35,20 +31,18 @@ namespace ipc {
|
|||||||
class MOZ_RAII MemMapSnapshot {
|
class MOZ_RAII MemMapSnapshot {
|
||||||
public:
|
public:
|
||||||
Result<Ok, nsresult> Init(size_t aSize);
|
Result<Ok, nsresult> Init(size_t aSize);
|
||||||
Result<Ok, nsresult> Finalize(loader::AutoMemMap& aMap);
|
Result<Ok, nsresult> Finalize(RefPtr<SharedMemory>& aMem);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
RangedPtr<T> Get() {
|
RangedPtr<T> Get() {
|
||||||
MOZ_ASSERT(mInitialized);
|
MOZ_ASSERT(mMem);
|
||||||
return {static_cast<T*>(mMem.memory()), mMem.max_size() / sizeof(T)};
|
return {static_cast<T*>(mMem->Memory()), mMem->MaxSize() / sizeof(T)};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
base::SharedMemory mMem;
|
RefPtr<SharedMemory> mMem;
|
||||||
bool mInitialized = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ipc
|
} // namespace mozilla::ipc
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
#endif // dom_ipc_MemMapSnapshot_h
|
#endif // dom_ipc_MemMapSnapshot_h
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ using mozilla::dom::BrowsingContextInitializer from "mozilla/dom/BrowsingContext
|
|||||||
using mozilla::dom::PermitUnloadResult from "nsIDocumentViewer.h";
|
using mozilla::dom::PermitUnloadResult from "nsIDocumentViewer.h";
|
||||||
using mozilla::dom::MaybeDiscardedWindowContext from "mozilla/dom/WindowContext.h";
|
using mozilla::dom::MaybeDiscardedWindowContext from "mozilla/dom/WindowContext.h";
|
||||||
using mozilla::dom::WindowContextTransaction from "mozilla/dom/WindowContext.h";
|
using mozilla::dom::WindowContextTransaction from "mozilla/dom/WindowContext.h";
|
||||||
[MoveOnly] using base::SharedMemoryHandle from "base/shared_memory.h";
|
[MoveOnly] using mozilla::ipc::SharedMemoryHandle from "mozilla/ipc/SharedMemory.h";
|
||||||
using gfxSparseBitSet from "gfxFontUtils.h";
|
using gfxSparseBitSet from "gfxFontUtils.h";
|
||||||
using FontVisibility from "gfxFontEntry.h";
|
using FontVisibility from "gfxFontEntry.h";
|
||||||
using mozilla::dom::MediaControlAction from "mozilla/dom/MediaControlKeySource.h";
|
using mozilla::dom::MediaControlAction from "mozilla/dom/MediaControlKeySource.h";
|
||||||
@@ -401,7 +401,7 @@ struct VisitedQueryResult
|
|||||||
struct StringBundleDescriptor
|
struct StringBundleDescriptor
|
||||||
{
|
{
|
||||||
nsCString bundleURL;
|
nsCString bundleURL;
|
||||||
FileDescriptor mapFile;
|
SharedMemoryHandle mapHandle;
|
||||||
uint32_t mapSize;
|
uint32_t mapSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -750,7 +750,7 @@ child:
|
|||||||
|
|
||||||
async RegisterStringBundles(StringBundleDescriptor[] stringBundles);
|
async RegisterStringBundles(StringBundleDescriptor[] stringBundles);
|
||||||
|
|
||||||
async UpdateSharedData(FileDescriptor mapFile, uint32_t aSize,
|
async UpdateSharedData(SharedMemoryHandle aMapHandle, uint32_t aSize,
|
||||||
IPCBlob[] blobs,
|
IPCBlob[] blobs,
|
||||||
nsCString[] changedKeys);
|
nsCString[] changedKeys);
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "MemMapSnapshot.h"
|
#include "MemMapSnapshot.h"
|
||||||
#include "ScriptPreloader-inl.h"
|
#include "ScriptPreloader-inl.h"
|
||||||
|
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/dom/AutoEntryScript.h"
|
#include "mozilla/dom/AutoEntryScript.h"
|
||||||
#include "mozilla/dom/BlobImpl.h"
|
#include "mozilla/dom/BlobImpl.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
@@ -41,12 +42,12 @@ static inline void AlignTo(size_t* aOffset, size_t aAlign) {
|
|||||||
|
|
||||||
SharedMap::SharedMap() = default;
|
SharedMap::SharedMap() = default;
|
||||||
|
|
||||||
SharedMap::SharedMap(nsIGlobalObject* aGlobal, const FileDescriptor& aMapFile,
|
SharedMap::SharedMap(nsIGlobalObject* aGlobal, SharedMemoryHandle&& aMapHandle,
|
||||||
size_t aMapSize, nsTArray<RefPtr<BlobImpl>>&& aBlobs)
|
size_t aMapSize, nsTArray<RefPtr<BlobImpl>>&& aBlobs)
|
||||||
: DOMEventTargetHelper(aGlobal), mBlobImpls(std::move(aBlobs)) {
|
: DOMEventTargetHelper(aGlobal),
|
||||||
mMapFile.reset(new FileDescriptor(aMapFile));
|
mBlobImpls(std::move(aBlobs)),
|
||||||
mMapSize = aMapSize;
|
mMapHandle(std::move(aMapHandle)),
|
||||||
}
|
mMapSize(aMapSize) {}
|
||||||
|
|
||||||
bool SharedMap::Has(const nsACString& aName) {
|
bool SharedMap::Has(const nsACString& aName) {
|
||||||
Unused << MaybeRebuild();
|
Unused << MaybeRebuild();
|
||||||
@@ -96,24 +97,20 @@ void SharedMap::Entry::Read(JSContext* aCx,
|
|||||||
holder.Read(aCx, aRetVal, aRv);
|
holder.Read(aCx, aRetVal, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileDescriptor SharedMap::CloneMapFile() const {
|
SharedMap::SharedMemoryHandle SharedMap::CloneHandle() const {
|
||||||
if (mMap.initialized()) {
|
if (mMap->IsValid()) {
|
||||||
return mMap.cloneHandle();
|
return mMap->CloneHandle();
|
||||||
}
|
}
|
||||||
return *mMapFile;
|
return SharedMemory::CloneHandle(mMapHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedMap::Update(const FileDescriptor& aMapFile, size_t aMapSize,
|
void SharedMap::Update(SharedMemoryHandle&& aMapHandle, size_t aMapSize,
|
||||||
nsTArray<RefPtr<BlobImpl>>&& aBlobs,
|
nsTArray<RefPtr<BlobImpl>>&& aBlobs,
|
||||||
nsTArray<nsCString>&& aChangedKeys) {
|
nsTArray<nsCString>&& aChangedKeys) {
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!mWritable);
|
MOZ_DIAGNOSTIC_ASSERT(!mWritable);
|
||||||
|
|
||||||
mMap.reset();
|
mMap->TakeHandleAndUnmap();
|
||||||
if (mMapFile) {
|
mMapHandle = std::move(aMapHandle);
|
||||||
*mMapFile = aMapFile;
|
|
||||||
} else {
|
|
||||||
mMapFile.reset(new FileDescriptor(aMapFile));
|
|
||||||
}
|
|
||||||
mMapSize = aMapSize;
|
mMapSize = aMapSize;
|
||||||
mEntries.Clear();
|
mEntries.Clear();
|
||||||
mEntryArray.reset();
|
mEntryArray.reset();
|
||||||
@@ -194,7 +191,7 @@ void SharedMap::Entry::ExtractData(char* aDestPtr, uint32_t aNewOffset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result<Ok, nsresult> SharedMap::MaybeRebuild() {
|
Result<Ok, nsresult> SharedMap::MaybeRebuild() {
|
||||||
if (!mMapFile) {
|
if (!SharedMemory::IsHandleValid(mMapHandle)) {
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,13 +203,19 @@ Result<Ok, nsresult> SharedMap::MaybeRebuild() {
|
|||||||
// its shared memory region. When needed, that structured clone data is
|
// its shared memory region. When needed, that structured clone data is
|
||||||
// retrieved directly as indexes into the SharedMap's shared memory region.
|
// retrieved directly as indexes into the SharedMap's shared memory region.
|
||||||
|
|
||||||
MOZ_TRY(mMap.initWithHandle(*mMapFile, mMapSize));
|
if (!mMap->SetHandle(SharedMemory::CloneHandle(mMapHandle),
|
||||||
mMapFile.reset();
|
SharedMemory::OpenRights::RightsReadOnly)) {
|
||||||
|
return Err(NS_ERROR_FAILURE);
|
||||||
|
}
|
||||||
|
mMapHandle = SharedMemory::NULLHandle();
|
||||||
|
if (!mMap->Map(mMapSize)) {
|
||||||
|
return Err(NS_ERROR_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// We should be able to pass this range as an initializer list or an immediate
|
// We should be able to pass this range as an initializer list or an immediate
|
||||||
// param, but gcc currently chokes on that if optimization is enabled, and
|
// param, but gcc currently chokes on that if optimization is enabled, and
|
||||||
// initializes everything to 0.
|
// initializes everything to 0.
|
||||||
Range<uint8_t> range(&mMap.get<uint8_t>()[0], mMap.size());
|
Range<uint8_t> range((uint8_t*)mMap->Memory(), mMap->Size());
|
||||||
InputBuffer buffer(range);
|
InputBuffer buffer(range);
|
||||||
|
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
@@ -245,7 +248,7 @@ WritableSharedMap::WritableSharedMap() {
|
|||||||
// Serialize the initial empty contents of the map immediately so that we
|
// Serialize the initial empty contents of the map immediately so that we
|
||||||
// always have a file descriptor to send to callers of CloneMapFile().
|
// always have a file descriptor to send to callers of CloneMapFile().
|
||||||
Unused << Serialize();
|
Unused << Serialize();
|
||||||
MOZ_RELEASE_ASSERT(mMap.initialized());
|
MOZ_RELEASE_ASSERT(mMap->IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedMap* WritableSharedMap::GetReadOnly() {
|
SharedMap* WritableSharedMap::GetReadOnly() {
|
||||||
@@ -253,7 +256,7 @@ SharedMap* WritableSharedMap::GetReadOnly() {
|
|||||||
nsTArray<RefPtr<BlobImpl>> blobs(mBlobImpls.Clone());
|
nsTArray<RefPtr<BlobImpl>> blobs(mBlobImpls.Clone());
|
||||||
mReadOnly =
|
mReadOnly =
|
||||||
new SharedMap(ContentProcessMessageManager::Get()->GetParentObject(),
|
new SharedMap(ContentProcessMessageManager::Get()->GetParentObject(),
|
||||||
CloneMapFile(), MapSize(), std::move(blobs));
|
CloneHandle(), MapSize(), std::move(blobs));
|
||||||
}
|
}
|
||||||
return mReadOnly;
|
return mReadOnly;
|
||||||
}
|
}
|
||||||
@@ -336,7 +339,7 @@ Result<Ok, nsresult> WritableSharedMap::Serialize() {
|
|||||||
memcpy(ptr.get(), header.Get(), header.cursor());
|
memcpy(ptr.get(), header.Get(), header.cursor());
|
||||||
|
|
||||||
// We've already updated offsets at this point. We need this to succeed.
|
// We've already updated offsets at this point. We need this to succeed.
|
||||||
mMap.reset();
|
mMap->TakeHandleAndUnmap();
|
||||||
MOZ_RELEASE_ASSERT(mem.Finalize(mMap).isOk());
|
MOZ_RELEASE_ASSERT(mem.Finalize(mMap).isOk());
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
@@ -352,7 +355,7 @@ void WritableSharedMap::SendTo(ContentParent* aParent) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Unused << aParent->SendUpdateSharedData(CloneMapFile(), mMap.size(), blobs,
|
Unused << aParent->SendUpdateSharedData(CloneHandle(), mMap->Size(), blobs,
|
||||||
mChangedKeys);
|
mChangedKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,7 +376,7 @@ void WritableSharedMap::BroadcastChanges() {
|
|||||||
|
|
||||||
if (mReadOnly) {
|
if (mReadOnly) {
|
||||||
nsTArray<RefPtr<BlobImpl>> blobImpls(mBlobImpls.Clone());
|
nsTArray<RefPtr<BlobImpl>> blobImpls(mBlobImpls.Clone());
|
||||||
mReadOnly->Update(CloneMapFile(), mMap.size(), std::move(blobImpls),
|
mReadOnly->Update(CloneHandle(), mMap->Size(), std::move(blobImpls),
|
||||||
std::move(mChangedKeys));
|
std::move(mChangedKeys));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
#include "mozilla/dom/MozSharedMapBinding.h"
|
#include "mozilla/dom/MozSharedMapBinding.h"
|
||||||
|
|
||||||
#include "mozilla/AutoMemMap.h"
|
|
||||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "mozilla/DOMEventTargetHelper.h"
|
#include "mozilla/DOMEventTargetHelper.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
@@ -53,12 +53,13 @@ namespace ipc {
|
|||||||
* WritableSharedMap instances.
|
* WritableSharedMap instances.
|
||||||
*/
|
*/
|
||||||
class SharedMap : public DOMEventTargetHelper {
|
class SharedMap : public DOMEventTargetHelper {
|
||||||
using FileDescriptor = mozilla::ipc::FileDescriptor;
|
using SharedMemory = mozilla::ipc::SharedMemory;
|
||||||
|
using SharedMemoryHandle = mozilla::ipc::SharedMemoryHandle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SharedMap();
|
SharedMap();
|
||||||
|
|
||||||
SharedMap(nsIGlobalObject* aGlobal, const FileDescriptor&, size_t,
|
SharedMap(nsIGlobalObject* aGlobal, SharedMemoryHandle&&, size_t,
|
||||||
nsTArray<RefPtr<BlobImpl>>&& aBlobs);
|
nsTArray<RefPtr<BlobImpl>>&& aBlobs);
|
||||||
|
|
||||||
// Returns true if the map contains the given (UTF-8) key.
|
// Returns true if the map contains the given (UTF-8) key.
|
||||||
@@ -96,7 +97,7 @@ class SharedMap : public DOMEventTargetHelper {
|
|||||||
* memory region for this map. The file descriptor may be passed between
|
* memory region for this map. The file descriptor may be passed between
|
||||||
* processes, and used to update corresponding instances in child processes.
|
* processes, and used to update corresponding instances in child processes.
|
||||||
*/
|
*/
|
||||||
FileDescriptor CloneMapFile() const;
|
SharedMemoryHandle CloneHandle() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the size of the memory mapped region that backs this map. Must be
|
* Returns the size of the memory mapped region that backs this map. Must be
|
||||||
@@ -104,14 +105,14 @@ class SharedMap : public DOMEventTargetHelper {
|
|||||||
* descriptor returned by CloneMapFile() in order to initialize or update a
|
* descriptor returned by CloneMapFile() in order to initialize or update a
|
||||||
* child SharedMap.
|
* child SharedMap.
|
||||||
*/
|
*/
|
||||||
size_t MapSize() const { return mMap.size(); }
|
size_t MapSize() const { return mMap->Size(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates this instance to reflect the contents of the shared memory region
|
* Updates this instance to reflect the contents of the shared memory region
|
||||||
* in the given map file, and broadcasts a change event for the given set of
|
* in the given map handle, and broadcasts a change event for the given set of
|
||||||
* changed (UTF-8-encoded) keys.
|
* changed (UTF-8-encoded) keys.
|
||||||
*/
|
*/
|
||||||
void Update(const FileDescriptor& aMapFile, size_t aMapSize,
|
void Update(SharedMemoryHandle&& aMapHandle, size_t aMapSize,
|
||||||
nsTArray<RefPtr<BlobImpl>>&& aBlobs,
|
nsTArray<RefPtr<BlobImpl>>&& aBlobs,
|
||||||
nsTArray<nsCString>&& aChangedKeys);
|
nsTArray<nsCString>&& aChangedKeys);
|
||||||
|
|
||||||
@@ -262,12 +263,8 @@ class SharedMap : public DOMEventTargetHelper {
|
|||||||
Result<Ok, nsresult> MaybeRebuild();
|
Result<Ok, nsresult> MaybeRebuild();
|
||||||
void MaybeRebuild() const;
|
void MaybeRebuild() const;
|
||||||
|
|
||||||
// Note: This header is included by WebIDL binding headers, and therefore
|
SharedMemoryHandle mMapHandle;
|
||||||
// can't include "windows.h". Since FileDescriptor.h does include "windows.h"
|
// The size of the memory-mapped region backed by mMap, in bytes.
|
||||||
// on Windows, we can only forward declare FileDescriptor, and can't include
|
|
||||||
// it as an inline member.
|
|
||||||
UniquePtr<FileDescriptor> mMapFile;
|
|
||||||
// The size of the memory-mapped region backed by mMapFile, in bytes.
|
|
||||||
size_t mMapSize = 0;
|
size_t mMapSize = 0;
|
||||||
|
|
||||||
mutable nsClassHashtable<nsCStringHashKey, Entry> mEntries;
|
mutable nsClassHashtable<nsCStringHashKey, Entry> mEntries;
|
||||||
@@ -276,14 +273,14 @@ class SharedMap : public DOMEventTargetHelper {
|
|||||||
// Manages the memory mapping of the current snapshot. This is initialized
|
// Manages the memory mapping of the current snapshot. This is initialized
|
||||||
// lazily after each SharedMap construction or updated, based on the values in
|
// lazily after each SharedMap construction or updated, based on the values in
|
||||||
// mMapFile and mMapSize.
|
// mMapFile and mMapSize.
|
||||||
loader::AutoMemMap mMap;
|
RefPtr<SharedMemory> mMap = MakeRefPtr<SharedMemory>();
|
||||||
|
|
||||||
bool mWritable = false;
|
bool mWritable = false;
|
||||||
|
|
||||||
// Returns a pointer to the beginning of the memory mapped snapshot. Entry
|
// Returns a pointer to the beginning of the memory mapped snapshot. Entry
|
||||||
// offsets are relative to this pointer, and Entry objects access their
|
// offsets are relative to this pointer, and Entry objects access their
|
||||||
// structured clone data by indexing this pointer.
|
// structured clone data by indexing this pointer.
|
||||||
char* Data() { return mMap.get<char>().get(); }
|
char* Data() { return static_cast<char*>(mMap->Memory()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WritableSharedMap final : public SharedMap {
|
class WritableSharedMap final : public SharedMap {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
#include "mozilla/BinarySearch.h"
|
#include "mozilla/BinarySearch.h"
|
||||||
#include "mozilla/Try.h"
|
#include "mozilla/Try.h"
|
||||||
#include "mozilla/ipc/FileDescriptor.h"
|
|
||||||
|
|
||||||
using namespace mozilla::loader;
|
using namespace mozilla::loader;
|
||||||
|
|
||||||
@@ -28,27 +27,42 @@ static inline size_t GetAlignmentOffset(size_t aOffset, size_t aAlign) {
|
|||||||
return mod ? aAlign - mod : 0;
|
return mod ? aAlign - mod : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedStringMap::SharedStringMap(const FileDescriptor& aMapFile,
|
SharedStringMap::SharedStringMap(const SharedMemoryHandle& aMapHandle,
|
||||||
size_t aMapSize) {
|
size_t aMapSize) {
|
||||||
auto result = mMap.initWithHandle(aMapFile, aMapSize);
|
auto map = MakeRefPtr<SharedMemory>();
|
||||||
MOZ_RELEASE_ASSERT(result.isOk());
|
{
|
||||||
MOZ_RELEASE_ASSERT(GetHeader().mMagic == kSharedStringMapMagic);
|
auto result = map->SetHandle(SharedMemory::CloneHandle(aMapHandle),
|
||||||
|
SharedMemory::OpenRights::RightsReadOnly);
|
||||||
|
MOZ_RELEASE_ASSERT(result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto result = map->Map(aMapSize);
|
||||||
|
MOZ_RELEASE_ASSERT(result);
|
||||||
|
}
|
||||||
|
|
||||||
// We return literal nsStrings and nsCStrings pointing to the mapped data,
|
// We return literal nsStrings and nsCStrings pointing to the mapped data,
|
||||||
// which means that we may still have references to the mapped data even
|
// which means that we may still have references to the mapped data even
|
||||||
// after this instance is destroyed. That means that we need to keep the
|
// after this instance is destroyed. That means that we need to keep the
|
||||||
// mapping alive until process shutdown, in order to be safe.
|
// mapping alive until process shutdown, in order to be safe.
|
||||||
mMap.setPersistent();
|
mMappedMemory = map->TakeMapping();
|
||||||
|
mHandle = map->TakeHandle();
|
||||||
|
|
||||||
|
MOZ_RELEASE_ASSERT(GetHeader().mMagic == kSharedStringMapMagic);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedStringMap::SharedStringMap(SharedStringMapBuilder&& aBuilder) {
|
SharedStringMap::SharedStringMap(SharedStringMapBuilder&& aBuilder) {
|
||||||
auto result = aBuilder.Finalize(mMap);
|
RefPtr<SharedMemory> map;
|
||||||
MOZ_RELEASE_ASSERT(result.isOk());
|
auto result = aBuilder.Finalize(map);
|
||||||
|
MOZ_RELEASE_ASSERT(result.isOk() && map);
|
||||||
|
|
||||||
|
mMappedMemory = map->TakeMapping();
|
||||||
|
mHandle = map->TakeHandle();
|
||||||
|
|
||||||
MOZ_RELEASE_ASSERT(GetHeader().mMagic == kSharedStringMapMagic);
|
MOZ_RELEASE_ASSERT(GetHeader().mMagic == kSharedStringMapMagic);
|
||||||
mMap.setPersistent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::ipc::FileDescriptor SharedStringMap::CloneFileDescriptor() const {
|
mozilla::ipc::SharedMemoryHandle SharedStringMap::CloneHandle() const {
|
||||||
return mMap.cloneHandle();
|
return SharedMemory::CloneHandle(mHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SharedStringMap::Has(const nsCString& aKey) {
|
bool SharedStringMap::Has(const nsCString& aKey) {
|
||||||
@@ -84,7 +98,7 @@ void SharedStringMapBuilder::Add(const nsCString& aKey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result<Ok, nsresult> SharedStringMapBuilder::Finalize(
|
Result<Ok, nsresult> SharedStringMapBuilder::Finalize(
|
||||||
loader::AutoMemMap& aMap) {
|
RefPtr<SharedMemory>& aMap) {
|
||||||
using Header = SharedStringMap::Header;
|
using Header = SharedStringMap::Header;
|
||||||
|
|
||||||
MOZ_ASSERT(mEntries.Count() == mKeyTable.Count());
|
MOZ_ASSERT(mEntries.Count() == mKeyTable.Count());
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
#ifndef dom_ipc_SharedStringMap_h
|
#ifndef dom_ipc_SharedStringMap_h
|
||||||
#define dom_ipc_SharedStringMap_h
|
#define dom_ipc_SharedStringMap_h
|
||||||
|
|
||||||
#include "mozilla/AutoMemMap.h"
|
|
||||||
#include "mozilla/Result.h"
|
#include "mozilla/Result.h"
|
||||||
#include "mozilla/dom/ipc/StringTable.h"
|
#include "mozilla/dom/ipc/StringTable.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "nsTHashMap.h"
|
#include "nsTHashMap.h"
|
||||||
|
|
||||||
namespace mozilla::dom::ipc {
|
namespace mozilla::dom::ipc {
|
||||||
@@ -30,8 +30,6 @@ class SharedStringMapBuilder;
|
|||||||
* freed before process shutdown. Do not use it for short-lived mappings.
|
* freed before process shutdown. Do not use it for short-lived mappings.
|
||||||
*/
|
*/
|
||||||
class SharedStringMap {
|
class SharedStringMap {
|
||||||
using FileDescriptor = mozilla::ipc::FileDescriptor;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* The header at the beginning of the shared memory region describing its
|
* The header at the beginning of the shared memory region describing its
|
||||||
@@ -90,7 +88,7 @@ class SharedStringMap {
|
|||||||
// Note: These constructors are infallible on the premise that this class
|
// Note: These constructors are infallible on the premise that this class
|
||||||
// is used primarily in cases where it is critical to platform
|
// is used primarily in cases where it is critical to platform
|
||||||
// functionality.
|
// functionality.
|
||||||
explicit SharedStringMap(const FileDescriptor&, size_t);
|
explicit SharedStringMap(const mozilla::ipc::SharedMemoryHandle&, size_t);
|
||||||
explicit SharedStringMap(SharedStringMapBuilder&&);
|
explicit SharedStringMap(SharedStringMapBuilder&&);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,21 +146,23 @@ class SharedStringMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a copy of the read-only file descriptor which backs the shared
|
* Returns a copy of the read-only shared memory handle which backs the shared
|
||||||
* memory region for this map. The file descriptor may be passed between
|
* memory region for this map. The handle may be passed between processes, and
|
||||||
* processes, and used to construct new instances of SharedStringMap with
|
* used to construct new instances of SharedStringMap with the same data as
|
||||||
* the same data as this instance.
|
* this instance.
|
||||||
*/
|
*/
|
||||||
FileDescriptor CloneFileDescriptor() const;
|
mozilla::ipc::SharedMemoryHandle CloneHandle() const;
|
||||||
|
|
||||||
size_t MapSize() const { return mMap.size(); }
|
size_t MapSize() const { return mMappedMemory.size(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~SharedStringMap() = default;
|
~SharedStringMap() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Type-safe getters for values in the shared memory region:
|
// Type-safe getters for values in the shared memory region:
|
||||||
const Header& GetHeader() const { return mMap.get<Header>()[0]; }
|
const Header& GetHeader() const {
|
||||||
|
return *reinterpret_cast<const Header*>(mMappedMemory.data());
|
||||||
|
}
|
||||||
|
|
||||||
RangedPtr<const Entry> Entries() const {
|
RangedPtr<const Entry> Entries() const {
|
||||||
return {reinterpret_cast<const Entry*>(&GetHeader() + 1), EntryCount()};
|
return {reinterpret_cast<const Entry*>(&GetHeader() + 1), EntryCount()};
|
||||||
@@ -171,18 +171,22 @@ class SharedStringMap {
|
|||||||
uint32_t EntryCount() const { return GetHeader().mEntryCount; }
|
uint32_t EntryCount() const { return GetHeader().mEntryCount; }
|
||||||
|
|
||||||
StringTable<nsCString> KeyTable() const {
|
StringTable<nsCString> KeyTable() const {
|
||||||
auto& header = GetHeader();
|
const auto& header = GetHeader();
|
||||||
return {{&mMap.get<uint8_t>()[header.mKeyStringsOffset],
|
return {{&mMappedMemory.data()[header.mKeyStringsOffset],
|
||||||
header.mKeyStringsSize}};
|
header.mKeyStringsSize}};
|
||||||
}
|
}
|
||||||
|
|
||||||
StringTable<nsString> ValueTable() const {
|
StringTable<nsString> ValueTable() const {
|
||||||
auto& header = GetHeader();
|
const auto& header = GetHeader();
|
||||||
return {{&mMap.get<uint8_t>()[header.mValueStringsOffset],
|
return {{&mMappedMemory.data()[header.mValueStringsOffset],
|
||||||
header.mValueStringsSize}};
|
header.mValueStringsSize}};
|
||||||
}
|
}
|
||||||
|
|
||||||
loader::AutoMemMap mMap;
|
mozilla::ipc::SharedMemoryHandle mHandle;
|
||||||
|
// This is a leaked shared memory mapping (see the constructor definition for
|
||||||
|
// an explanation). It replaces AutoMemMap::setPersistent behavior as part of
|
||||||
|
// bug 1454816.
|
||||||
|
Span<uint8_t> mMappedMemory;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -201,10 +205,10 @@ class MOZ_RAII SharedStringMapBuilder {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finalizes the binary representation of the map, writes it to a shared
|
* Finalizes the binary representation of the map, writes it to a shared
|
||||||
* memory region, and then initializes the given AutoMemMap with a reference
|
* memory region, and then initializes the given SharedMemory with a reference
|
||||||
* to the read-only copy of it.
|
* to the read-only copy of it.
|
||||||
*/
|
*/
|
||||||
Result<Ok, nsresult> Finalize(loader::AutoMemMap& aMap);
|
Result<Ok, nsresult> Finalize(RefPtr<mozilla::ipc::SharedMemory>& aMap);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Entry = SharedStringMap::Entry;
|
using Entry = SharedStringMap::Entry;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||||
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
||||||
# include "mozilla/SandboxInfo.h"
|
# include "mozilla/SandboxInfo.h"
|
||||||
# include "base/shared_memory.h"
|
# include "mozilla/ipc/SharedMemory.h"
|
||||||
#endif
|
#endif
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/SSE.h"
|
#include "mozilla/SSE.h"
|
||||||
@@ -302,7 +302,7 @@ class NotifyGMPProcessLoadedTask : public Runnable {
|
|||||||
|
|
||||||
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
||||||
if (SandboxInfo::Get().Test(SandboxInfo::kEnabledForMedia) &&
|
if (SandboxInfo::Get().Test(SandboxInfo::kEnabledForMedia) &&
|
||||||
base::SharedMemory::UsingPosixShm()) {
|
ipc::SharedMemory::UsingPosixShm()) {
|
||||||
canProfile = false;
|
canProfile = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,13 +7,14 @@
|
|||||||
|
|
||||||
#include "SharedFontList.h"
|
#include "SharedFontList.h"
|
||||||
|
|
||||||
#include "base/shared_memory.h"
|
#include "base/process.h"
|
||||||
|
|
||||||
#include "gfxFontUtils.h"
|
#include "gfxFontUtils.h"
|
||||||
#include "nsClassHashtable.h"
|
#include "nsClassHashtable.h"
|
||||||
#include "nsTHashMap.h"
|
#include "nsTHashMap.h"
|
||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
|
|
||||||
// This is split out from SharedFontList.h because that header is included
|
// This is split out from SharedFontList.h because that header is included
|
||||||
// quite widely (via gfxPlatformFontList.h, gfxTextRun.h, etc), and other code
|
// quite widely (via gfxPlatformFontList.h, gfxTextRun.h, etc), and other code
|
||||||
@@ -242,11 +243,11 @@ class FontList {
|
|||||||
* list has changed/grown since the child was first initialized).
|
* list has changed/grown since the child was first initialized).
|
||||||
*/
|
*/
|
||||||
void ShareShmBlockToProcess(uint32_t aIndex, base::ProcessId aPid,
|
void ShareShmBlockToProcess(uint32_t aIndex, base::ProcessId aPid,
|
||||||
base::SharedMemoryHandle* aOut) {
|
ipc::SharedMemory::Handle* aOut) {
|
||||||
MOZ_RELEASE_ASSERT(mReadOnlyShmems.Length() == mBlocks.Length());
|
MOZ_RELEASE_ASSERT(mReadOnlyShmems.Length() == mBlocks.Length());
|
||||||
if (aIndex >= mReadOnlyShmems.Length()) {
|
if (aIndex >= mReadOnlyShmems.Length()) {
|
||||||
// Block index out of range
|
// Block index out of range
|
||||||
*aOut = base::SharedMemory::NULLHandle();
|
*aOut = ipc::SharedMemory::NULLHandle();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*aOut = mReadOnlyShmems[aIndex]->CloneHandle();
|
*aOut = mReadOnlyShmems[aIndex]->CloneHandle();
|
||||||
@@ -260,14 +261,14 @@ class FontList {
|
|||||||
* shared to the given process. This is used at child process startup
|
* shared to the given process. This is used at child process startup
|
||||||
* to pass the complete list at once.
|
* to pass the complete list at once.
|
||||||
*/
|
*/
|
||||||
void ShareBlocksToProcess(nsTArray<base::SharedMemoryHandle>* aBlocks,
|
void ShareBlocksToProcess(nsTArray<ipc::SharedMemory::Handle>* aBlocks,
|
||||||
base::ProcessId aPid);
|
base::ProcessId aPid);
|
||||||
|
|
||||||
base::SharedMemoryHandle ShareBlockToProcess(uint32_t aIndex,
|
ipc::SharedMemory::Handle ShareBlockToProcess(uint32_t aIndex,
|
||||||
base::ProcessId aPid);
|
base::ProcessId aPid);
|
||||||
|
|
||||||
void ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
|
void ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
|
||||||
base::SharedMemoryHandle aHandle);
|
ipc::SharedMemory::Handle aHandle);
|
||||||
/**
|
/**
|
||||||
* Support for memory reporter.
|
* Support for memory reporter.
|
||||||
*/
|
*/
|
||||||
@@ -299,11 +300,11 @@ class FontList {
|
|||||||
struct ShmBlock {
|
struct ShmBlock {
|
||||||
// Takes ownership of aShmem. Note that in a child process, aShmem will be
|
// Takes ownership of aShmem. Note that in a child process, aShmem will be
|
||||||
// mapped as read-only.
|
// mapped as read-only.
|
||||||
explicit ShmBlock(mozilla::UniquePtr<base::SharedMemory>&& aShmem)
|
explicit ShmBlock(RefPtr<ipc::SharedMemory>&& aShmem)
|
||||||
: mShmem(std::move(aShmem)) {}
|
: mShmem(std::move(aShmem)) {}
|
||||||
|
|
||||||
// Get pointer to the mapped memory.
|
// Get pointer to the mapped memory.
|
||||||
void* Memory() const { return mShmem->memory(); }
|
void* Memory() const { return mShmem->Memory(); }
|
||||||
|
|
||||||
// Only the parent process does allocation, so only it will update this
|
// Only the parent process does allocation, so only it will update this
|
||||||
// field. Content processes read the value when checking Pointer validity.
|
// field. Content processes read the value when checking Pointer validity.
|
||||||
@@ -325,7 +326,7 @@ class FontList {
|
|||||||
return static_cast<BlockHeader*>(Memory())->mBlockSize;
|
return static_cast<BlockHeader*>(Memory())->mBlockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::UniquePtr<base::SharedMemory> mShmem;
|
RefPtr<ipc::SharedMemory> mShmem;
|
||||||
};
|
};
|
||||||
|
|
||||||
Header& GetHeader() const;
|
Header& GetHeader() const;
|
||||||
@@ -371,7 +372,7 @@ class FontList {
|
|||||||
* Auxiliary array, used only in the parent process; holds read-only copies
|
* Auxiliary array, used only in the parent process; holds read-only copies
|
||||||
* of the shmem blocks; these are what will be shared to child processes.
|
* of the shmem blocks; these are what will be shared to child processes.
|
||||||
*/
|
*/
|
||||||
nsTArray<mozilla::UniquePtr<base::SharedMemory>> mReadOnlyShmems;
|
nsTArray<RefPtr<ipc::SharedMemory>> mReadOnlyShmems;
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
// Bool array to track whether we have read face names from the name table.
|
// Bool array to track whether we have read face names from the name table.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "gfxPlatformFontList.h"
|
#include "gfxPlatformFontList.h"
|
||||||
#include "gfxFontUtils.h"
|
#include "gfxFontUtils.h"
|
||||||
#include "gfxFont.h"
|
#include "gfxFont.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
#include "prerror.h"
|
#include "prerror.h"
|
||||||
#include "mozilla/dom/ContentChild.h"
|
#include "mozilla/dom/ContentChild.h"
|
||||||
@@ -738,22 +739,23 @@ FontList::FontList(uint32_t aGeneration) {
|
|||||||
// SetXPCOMProcessAttributes.
|
// SetXPCOMProcessAttributes.
|
||||||
auto& blocks = dom::ContentChild::GetSingleton()->SharedFontListBlocks();
|
auto& blocks = dom::ContentChild::GetSingleton()->SharedFontListBlocks();
|
||||||
for (auto& handle : blocks) {
|
for (auto& handle : blocks) {
|
||||||
auto newShm = MakeUnique<base::SharedMemory>();
|
auto newShm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (!newShm->IsHandleValid(handle)) {
|
if (!newShm->IsHandleValid(handle)) {
|
||||||
// Bail out and let UpdateShmBlocks try to do its thing below.
|
// Bail out and let UpdateShmBlocks try to do its thing below.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!newShm->SetHandle(std::move(handle), true)) {
|
if (!newShm->SetHandle(std::move(handle),
|
||||||
|
ipc::SharedMemory::OpenRights::RightsReadOnly)) {
|
||||||
MOZ_CRASH("failed to set shm handle");
|
MOZ_CRASH("failed to set shm handle");
|
||||||
}
|
}
|
||||||
if (!newShm->Map(SHM_BLOCK_SIZE) || !newShm->memory()) {
|
if (!newShm->Map(SHM_BLOCK_SIZE) || !newShm->Memory()) {
|
||||||
MOZ_CRASH("failed to map shared memory");
|
MOZ_CRASH("failed to map shared memory");
|
||||||
}
|
}
|
||||||
uint32_t size = static_cast<BlockHeader*>(newShm->memory())->mBlockSize;
|
uint32_t size = static_cast<BlockHeader*>(newShm->Memory())->mBlockSize;
|
||||||
MOZ_ASSERT(size >= SHM_BLOCK_SIZE);
|
MOZ_ASSERT(size >= SHM_BLOCK_SIZE);
|
||||||
if (size != SHM_BLOCK_SIZE) {
|
if (size != SHM_BLOCK_SIZE) {
|
||||||
newShm->Unmap();
|
newShm->Unmap();
|
||||||
if (!newShm->Map(size) || !newShm->memory()) {
|
if (!newShm->Map(size) || !newShm->Memory()) {
|
||||||
MOZ_CRASH("failed to map shared memory");
|
MOZ_CRASH("failed to map shared memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -800,16 +802,16 @@ FontList::Header& FontList::GetHeader() const MOZ_NO_THREAD_SAFETY_ANALYSIS {
|
|||||||
bool FontList::AppendShmBlock(uint32_t aSizeNeeded) {
|
bool FontList::AppendShmBlock(uint32_t aSizeNeeded) {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
uint32_t size = std::max(aSizeNeeded, SHM_BLOCK_SIZE);
|
uint32_t size = std::max(aSizeNeeded, SHM_BLOCK_SIZE);
|
||||||
auto newShm = MakeUnique<base::SharedMemory>();
|
auto newShm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (!newShm->CreateFreezeable(size)) {
|
if (!newShm->CreateFreezable(size)) {
|
||||||
MOZ_CRASH("failed to create shared memory");
|
MOZ_CRASH("failed to create shared memory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!newShm->Map(size) || !newShm->memory()) {
|
if (!newShm->Map(size) || !newShm->Memory()) {
|
||||||
MOZ_CRASH("failed to map shared memory");
|
MOZ_CRASH("failed to map shared memory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto readOnly = MakeUnique<base::SharedMemory>();
|
auto readOnly = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (!newShm->ReadOnlyCopy(readOnly.get())) {
|
if (!newShm->ReadOnlyCopy(readOnly.get())) {
|
||||||
MOZ_CRASH("failed to create read-only copy");
|
MOZ_CRASH("failed to create read-only copy");
|
||||||
return false;
|
return false;
|
||||||
@@ -844,15 +846,16 @@ bool FontList::AppendShmBlock(uint32_t aSizeNeeded) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FontList::ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
|
void FontList::ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
|
||||||
base::SharedMemoryHandle aHandle) {
|
ipc::SharedMemory::Handle aHandle) {
|
||||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||||
MOZ_ASSERT(mBlocks.Length() > 0);
|
MOZ_ASSERT(mBlocks.Length() > 0);
|
||||||
|
|
||||||
auto newShm = MakeUnique<base::SharedMemory>();
|
auto newShm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (!newShm->IsHandleValid(aHandle)) {
|
if (!newShm->IsHandleValid(aHandle)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!newShm->SetHandle(std::move(aHandle), true)) {
|
if (!newShm->SetHandle(std::move(aHandle),
|
||||||
|
ipc::SharedMemory::RightsReadOnly)) {
|
||||||
MOZ_CRASH("failed to set shm handle");
|
MOZ_CRASH("failed to set shm handle");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,15 +866,15 @@ void FontList::ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newShm->Map(SHM_BLOCK_SIZE) || !newShm->memory()) {
|
if (!newShm->Map(SHM_BLOCK_SIZE) || !newShm->Memory()) {
|
||||||
MOZ_CRASH("failed to map shared memory");
|
MOZ_CRASH("failed to map shared memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t size = static_cast<BlockHeader*>(newShm->memory())->mBlockSize;
|
uint32_t size = static_cast<BlockHeader*>(newShm->Memory())->mBlockSize;
|
||||||
MOZ_ASSERT(size >= SHM_BLOCK_SIZE);
|
MOZ_ASSERT(size >= SHM_BLOCK_SIZE);
|
||||||
if (size != SHM_BLOCK_SIZE) {
|
if (size != SHM_BLOCK_SIZE) {
|
||||||
newShm->Unmap();
|
newShm->Unmap();
|
||||||
if (!newShm->Map(size) || !newShm->memory()) {
|
if (!newShm->Map(size) || !newShm->Memory()) {
|
||||||
MOZ_CRASH("failed to map shared memory");
|
MOZ_CRASH("failed to map shared memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -892,26 +895,27 @@ FontList::ShmBlock* FontList::GetBlockFromParent(uint32_t aIndex) {
|
|||||||
// If we have no existing blocks, we don't want a generation check yet;
|
// If we have no existing blocks, we don't want a generation check yet;
|
||||||
// the header in the first block will define the generation of this list
|
// the header in the first block will define the generation of this list
|
||||||
uint32_t generation = aIndex == 0 ? 0 : GetGeneration();
|
uint32_t generation = aIndex == 0 ? 0 : GetGeneration();
|
||||||
base::SharedMemoryHandle handle = base::SharedMemory::NULLHandle();
|
ipc::SharedMemory::Handle handle = ipc::SharedMemory::NULLHandle();
|
||||||
if (!dom::ContentChild::GetSingleton()->SendGetFontListShmBlock(
|
if (!dom::ContentChild::GetSingleton()->SendGetFontListShmBlock(
|
||||||
generation, aIndex, &handle)) {
|
generation, aIndex, &handle)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto newShm = MakeUnique<base::SharedMemory>();
|
auto newShm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (!newShm->IsHandleValid(handle)) {
|
if (!newShm->IsHandleValid(handle)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (!newShm->SetHandle(std::move(handle), true)) {
|
if (!newShm->SetHandle(std::move(handle),
|
||||||
|
ipc::SharedMemory::RightsReadOnly)) {
|
||||||
MOZ_CRASH("failed to set shm handle");
|
MOZ_CRASH("failed to set shm handle");
|
||||||
}
|
}
|
||||||
if (!newShm->Map(SHM_BLOCK_SIZE) || !newShm->memory()) {
|
if (!newShm->Map(SHM_BLOCK_SIZE) || !newShm->Memory()) {
|
||||||
MOZ_CRASH("failed to map shared memory");
|
MOZ_CRASH("failed to map shared memory");
|
||||||
}
|
}
|
||||||
uint32_t size = static_cast<BlockHeader*>(newShm->memory())->mBlockSize;
|
uint32_t size = static_cast<BlockHeader*>(newShm->Memory())->mBlockSize;
|
||||||
MOZ_ASSERT(size >= SHM_BLOCK_SIZE);
|
MOZ_ASSERT(size >= SHM_BLOCK_SIZE);
|
||||||
if (size != SHM_BLOCK_SIZE) {
|
if (size != SHM_BLOCK_SIZE) {
|
||||||
newShm->Unmap();
|
newShm->Unmap();
|
||||||
if (!newShm->Map(size) || !newShm->memory()) {
|
if (!newShm->Map(size) || !newShm->Memory()) {
|
||||||
MOZ_CRASH("failed to map shared memory");
|
MOZ_CRASH("failed to map shared memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -940,8 +944,8 @@ bool FontList::UpdateShmBlocks(bool aMustLock) MOZ_NO_THREAD_SAFETY_ANALYSIS {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FontList::ShareBlocksToProcess(nsTArray<base::SharedMemoryHandle>* aBlocks,
|
void FontList::ShareBlocksToProcess(
|
||||||
base::ProcessId aPid) {
|
nsTArray<ipc::SharedMemory::Handle>* aBlocks, base::ProcessId aPid) {
|
||||||
MOZ_RELEASE_ASSERT(mReadOnlyShmems.Length() == mBlocks.Length());
|
MOZ_RELEASE_ASSERT(mReadOnlyShmems.Length() == mBlocks.Length());
|
||||||
for (auto& shmem : mReadOnlyShmems) {
|
for (auto& shmem : mReadOnlyShmems) {
|
||||||
auto handle = shmem->CloneHandle();
|
auto handle = shmem->CloneHandle();
|
||||||
@@ -957,8 +961,8 @@ void FontList::ShareBlocksToProcess(nsTArray<base::SharedMemoryHandle>* aBlocks,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base::SharedMemoryHandle FontList::ShareBlockToProcess(uint32_t aIndex,
|
ipc::SharedMemory::Handle FontList::ShareBlockToProcess(uint32_t aIndex,
|
||||||
base::ProcessId aPid) {
|
base::ProcessId aPid) {
|
||||||
MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
|
MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
|
||||||
MOZ_RELEASE_ASSERT(mReadOnlyShmems.Length() == mBlocks.Length());
|
MOZ_RELEASE_ASSERT(mReadOnlyShmems.Length() == mBlocks.Length());
|
||||||
MOZ_RELEASE_ASSERT(aIndex < mReadOnlyShmems.Length());
|
MOZ_RELEASE_ASSERT(aIndex < mReadOnlyShmems.Length());
|
||||||
|
|||||||
@@ -3044,7 +3044,7 @@ void gfxPlatformFontList::CancelInitOtherFamilyNamesTask() {
|
|||||||
|
|
||||||
void gfxPlatformFontList::ShareFontListShmBlockToProcess(
|
void gfxPlatformFontList::ShareFontListShmBlockToProcess(
|
||||||
uint32_t aGeneration, uint32_t aIndex, base::ProcessId aPid,
|
uint32_t aGeneration, uint32_t aIndex, base::ProcessId aPid,
|
||||||
base::SharedMemoryHandle* aOut) {
|
mozilla::ipc::SharedMemory::Handle* aOut) {
|
||||||
auto list = SharedFontList();
|
auto list = SharedFontList();
|
||||||
if (!list) {
|
if (!list) {
|
||||||
return;
|
return;
|
||||||
@@ -3052,26 +3052,28 @@ void gfxPlatformFontList::ShareFontListShmBlockToProcess(
|
|||||||
if (!aGeneration || list->GetGeneration() == aGeneration) {
|
if (!aGeneration || list->GetGeneration() == aGeneration) {
|
||||||
list->ShareShmBlockToProcess(aIndex, aPid, aOut);
|
list->ShareShmBlockToProcess(aIndex, aPid, aOut);
|
||||||
} else {
|
} else {
|
||||||
*aOut = base::SharedMemory::NULLHandle();
|
*aOut = mozilla::ipc::SharedMemory::NULLHandle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfxPlatformFontList::ShareFontListToProcess(
|
void gfxPlatformFontList::ShareFontListToProcess(
|
||||||
nsTArray<base::SharedMemoryHandle>* aBlocks, base::ProcessId aPid) {
|
nsTArray<mozilla::ipc::SharedMemory::Handle>* aBlocks,
|
||||||
|
base::ProcessId aPid) {
|
||||||
auto list = SharedFontList();
|
auto list = SharedFontList();
|
||||||
if (list) {
|
if (list) {
|
||||||
list->ShareBlocksToProcess(aBlocks, aPid);
|
list->ShareBlocksToProcess(aBlocks, aPid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base::SharedMemoryHandle gfxPlatformFontList::ShareShmBlockToProcess(
|
mozilla::ipc::SharedMemory::Handle gfxPlatformFontList::ShareShmBlockToProcess(
|
||||||
uint32_t aIndex, base::ProcessId aPid) {
|
uint32_t aIndex, base::ProcessId aPid) {
|
||||||
MOZ_RELEASE_ASSERT(SharedFontList());
|
MOZ_RELEASE_ASSERT(SharedFontList());
|
||||||
return SharedFontList()->ShareBlockToProcess(aIndex, aPid);
|
return SharedFontList()->ShareBlockToProcess(aIndex, aPid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfxPlatformFontList::ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
|
void gfxPlatformFontList::ShmBlockAdded(
|
||||||
base::SharedMemoryHandle aHandle) {
|
uint32_t aGeneration, uint32_t aIndex,
|
||||||
|
mozilla::ipc::SharedMemory::Handle aHandle) {
|
||||||
if (SharedFontList()) {
|
if (SharedFontList()) {
|
||||||
AutoLock lock(mLock);
|
AutoLock lock(mLock);
|
||||||
SharedFontList()->ShmBlockAdded(aGeneration, aIndex, std::move(aHandle));
|
SharedFontList()->ShmBlockAdded(aGeneration, aIndex, std::move(aHandle));
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "gfxPlatform.h"
|
#include "gfxPlatform.h"
|
||||||
#include "SharedFontList.h"
|
#include "SharedFontList.h"
|
||||||
|
|
||||||
|
#include "base/process.h"
|
||||||
#include "nsIMemoryReporter.h"
|
#include "nsIMemoryReporter.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/EnumeratedArray.h"
|
#include "mozilla/EnumeratedArray.h"
|
||||||
@@ -26,10 +27,9 @@
|
|||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/RangedArray.h"
|
#include "mozilla/RangedArray.h"
|
||||||
#include "mozilla/RecursiveMutex.h"
|
#include "mozilla/RecursiveMutex.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "nsLanguageAtomService.h"
|
#include "nsLanguageAtomService.h"
|
||||||
|
|
||||||
#include "base/shared_memory.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace fontlist {
|
namespace fontlist {
|
||||||
struct AliasData;
|
struct AliasData;
|
||||||
@@ -355,18 +355,19 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
|
|||||||
// be shared to the given processId.
|
// be shared to the given processId.
|
||||||
void ShareFontListShmBlockToProcess(uint32_t aGeneration, uint32_t aIndex,
|
void ShareFontListShmBlockToProcess(uint32_t aGeneration, uint32_t aIndex,
|
||||||
base::ProcessId aPid,
|
base::ProcessId aPid,
|
||||||
base::SharedMemoryHandle* aOut);
|
mozilla::ipc::SharedMemory::Handle* aOut);
|
||||||
|
|
||||||
// Populate the array aBlocks with the complete list of shmem handles ready
|
// Populate the array aBlocks with the complete list of shmem handles ready
|
||||||
// to be shared to the given processId.
|
// to be shared to the given processId.
|
||||||
void ShareFontListToProcess(nsTArray<base::SharedMemoryHandle>* aBlocks,
|
void ShareFontListToProcess(
|
||||||
base::ProcessId aPid);
|
nsTArray<mozilla::ipc::SharedMemory::Handle>* aBlocks,
|
||||||
|
base::ProcessId aPid);
|
||||||
|
|
||||||
void ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
|
void ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
|
||||||
base::SharedMemoryHandle aHandle);
|
mozilla::ipc::SharedMemory::Handle aHandle);
|
||||||
|
|
||||||
base::SharedMemoryHandle ShareShmBlockToProcess(uint32_t aIndex,
|
mozilla::ipc::SharedMemory::Handle ShareShmBlockToProcess(
|
||||||
base::ProcessId aPid);
|
uint32_t aIndex, base::ProcessId aPid);
|
||||||
|
|
||||||
void SetCharacterMap(uint32_t aGeneration, uint32_t aFamilyIndex, bool aAlias,
|
void SetCharacterMap(uint32_t aGeneration, uint32_t aFamilyIndex, bool aAlias,
|
||||||
uint32_t aFaceIndex, const gfxSparseBitSet& aMap);
|
uint32_t aFaceIndex, const gfxSparseBitSet& aMap);
|
||||||
|
|||||||
@@ -330,11 +330,11 @@ void nsHyphenationManager::LoadAliases() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void nsHyphenationManager::ShareHyphDictToProcess(
|
void nsHyphenationManager::ShareHyphDictToProcess(
|
||||||
nsIURI* aURI, base::ProcessId aPid, base::SharedMemoryHandle* aOutHandle,
|
nsIURI* aURI, base::ProcessId aPid,
|
||||||
uint32_t* aOutSize) {
|
mozilla::ipc::SharedMemory::Handle* aOutHandle, uint32_t* aOutSize) {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
// aURI will be referring to an omnijar resource (otherwise just bail).
|
// aURI will be referring to an omnijar resource (otherwise just bail).
|
||||||
*aOutHandle = base::SharedMemory::NULLHandle();
|
*aOutHandle = mozilla::ipc::SharedMemory::NULLHandle();
|
||||||
*aOutSize = 0;
|
*aOutSize = 0;
|
||||||
|
|
||||||
// Extract the locale code from the URI, and get the corresponding
|
// Extract the locale code from the URI, and get the corresponding
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
#ifndef nsHyphenationManager_h__
|
#ifndef nsHyphenationManager_h__
|
||||||
#define nsHyphenationManager_h__
|
#define nsHyphenationManager_h__
|
||||||
|
|
||||||
#include "base/shared_memory.h"
|
#include "base/process.h"
|
||||||
#include "mozilla/Omnijar.h"
|
#include "mozilla/Omnijar.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "nsAtomHashKeys.h"
|
#include "nsAtomHashKeys.h"
|
||||||
#include "nsInterfaceHashtable.h"
|
#include "nsInterfaceHashtable.h"
|
||||||
@@ -27,7 +28,7 @@ class nsHyphenationManager : public nsIObserver {
|
|||||||
already_AddRefed<nsHyphenator> GetHyphenator(nsAtom* aLocale);
|
already_AddRefed<nsHyphenator> GetHyphenator(nsAtom* aLocale);
|
||||||
|
|
||||||
void ShareHyphDictToProcess(nsIURI* aURI, base::ProcessId aPid,
|
void ShareHyphDictToProcess(nsIURI* aURI, base::ProcessId aPid,
|
||||||
base::SharedMemoryHandle* aOutHandle,
|
mozilla::ipc::SharedMemory::Handle* aOutHandle,
|
||||||
uint32_t* aOutSize);
|
uint32_t* aOutSize);
|
||||||
|
|
||||||
static nsHyphenationManager* Instance();
|
static nsHyphenationManager* Instance();
|
||||||
|
|||||||
@@ -66,27 +66,27 @@ static const void* GetItemPtrFromJarURI(nsIJARURI* aJAR, uint32_t* aLength) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UniquePtr<base::SharedMemory> GetHyphDictFromParent(nsIURI* aURI,
|
static RefPtr<ipc::SharedMemory> GetHyphDictFromParent(nsIURI* aURI,
|
||||||
uint32_t* aLength) {
|
uint32_t* aLength) {
|
||||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||||
base::SharedMemoryHandle handle = base::SharedMemory::NULLHandle();
|
ipc::SharedMemory::Handle handle = ipc::SharedMemory::NULLHandle();
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
MOZ_ASSERT(aURI);
|
MOZ_ASSERT(aURI);
|
||||||
if (!dom::ContentChild::GetSingleton()->SendGetHyphDict(aURI, &handle,
|
if (!dom::ContentChild::GetSingleton()->SendGetHyphDict(aURI, &handle,
|
||||||
&size)) {
|
&size)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
UniquePtr<base::SharedMemory> shm = MakeUnique<base::SharedMemory>();
|
RefPtr<ipc::SharedMemory> shm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (!shm->IsHandleValid(handle)) {
|
if (!shm->IsHandleValid(handle)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (!shm->SetHandle(std::move(handle), true)) {
|
if (!shm->SetHandle(std::move(handle), ipc::SharedMemory::RightsReadOnly)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (!shm->Map(size)) {
|
if (!shm->Map(size)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
char* addr = static_cast<char*>(shm->memory());
|
char* addr = static_cast<char*>(shm->Memory());
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -94,21 +94,21 @@ static UniquePtr<base::SharedMemory> GetHyphDictFromParent(nsIURI* aURI,
|
|||||||
return shm;
|
return shm;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UniquePtr<base::SharedMemory> CopyToShmem(const CompiledData* aData) {
|
static RefPtr<ipc::SharedMemory> CopyToShmem(const CompiledData* aData) {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
|
|
||||||
// The shm-related calls here are not expected to fail, but if they do,
|
// The shm-related calls here are not expected to fail, but if they do,
|
||||||
// we'll just return null (as if the resource was unavailable) and proceed
|
// we'll just return null (as if the resource was unavailable) and proceed
|
||||||
// without hyphenation.
|
// without hyphenation.
|
||||||
uint32_t size = mapped_hyph_compiled_data_size(aData);
|
uint32_t size = mapped_hyph_compiled_data_size(aData);
|
||||||
UniquePtr<base::SharedMemory> shm = MakeUnique<base::SharedMemory>();
|
RefPtr<ipc::SharedMemory> shm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (!shm->CreateFreezeable(size)) {
|
if (!shm->CreateFreezable(size)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (!shm->Map(size)) {
|
if (!shm->Map(size)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
char* buffer = static_cast<char*>(shm->memory());
|
char* buffer = static_cast<char*>(shm->Memory());
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -121,9 +121,8 @@ static UniquePtr<base::SharedMemory> CopyToShmem(const CompiledData* aData) {
|
|||||||
return shm;
|
return shm;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UniquePtr<base::SharedMemory> LoadFromURI(nsIURI* aURI,
|
static RefPtr<ipc::SharedMemory> LoadFromURI(nsIURI* aURI, uint32_t* aLength,
|
||||||
uint32_t* aLength,
|
bool aPrecompiled) {
|
||||||
bool aPrecompiled) {
|
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
nsCOMPtr<nsIChannel> channel;
|
nsCOMPtr<nsIChannel> channel;
|
||||||
if (NS_FAILED(NS_NewChannel(
|
if (NS_FAILED(NS_NewChannel(
|
||||||
@@ -146,14 +145,14 @@ static UniquePtr<base::SharedMemory> LoadFromURI(nsIURI* aURI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (aPrecompiled) {
|
if (aPrecompiled) {
|
||||||
UniquePtr<base::SharedMemory> shm = MakeUnique<base::SharedMemory>();
|
RefPtr<ipc::SharedMemory> shm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (!shm->CreateFreezeable(available)) {
|
if (!shm->CreateFreezable(available)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (!shm->Map(available)) {
|
if (!shm->Map(available)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
char* buffer = static_cast<char*>(shm->memory());
|
char* buffer = static_cast<char*>(shm->Memory());
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -212,7 +211,7 @@ nsHyphenator::nsHyphenator(nsIURI* aURI, bool aHyphenateCapitalized)
|
|||||||
// compilation once per language per session.
|
// compilation once per language per session.
|
||||||
if (!precompiled && !XRE_IsParentProcess()) {
|
if (!precompiled && !XRE_IsParentProcess()) {
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
UniquePtr<base::SharedMemory> shm = GetHyphDictFromParent(aURI, &length);
|
RefPtr<ipc::SharedMemory> shm = GetHyphDictFromParent(aURI, &length);
|
||||||
if (shm) {
|
if (shm) {
|
||||||
// We don't need to validate mDict because the parent process
|
// We don't need to validate mDict because the parent process
|
||||||
// will have done so.
|
// will have done so.
|
||||||
@@ -246,7 +245,7 @@ nsHyphenator::nsHyphenator(nsIURI* aURI, bool aHyphenateCapitalized)
|
|||||||
UniquePtr<const CompiledData> data(mapped_hyph_compile_buffer(
|
UniquePtr<const CompiledData> data(mapped_hyph_compile_buffer(
|
||||||
static_cast<const uint8_t*>(ptr), length, false));
|
static_cast<const uint8_t*>(ptr), length, false));
|
||||||
if (data) {
|
if (data) {
|
||||||
UniquePtr<base::SharedMemory> shm = CopyToShmem(data.get());
|
RefPtr<ipc::SharedMemory> shm = CopyToShmem(data.get());
|
||||||
if (shm) {
|
if (shm) {
|
||||||
mDictSize = mapped_hyph_compiled_data_size(data.get());
|
mDictSize = mapped_hyph_compiled_data_size(data.get());
|
||||||
mDict = AsVariant(std::move(shm));
|
mDict = AsVariant(std::move(shm));
|
||||||
@@ -260,16 +259,14 @@ nsHyphenator::nsHyphenator(nsIURI* aURI, bool aHyphenateCapitalized)
|
|||||||
// buffer; if we're a child, send a request to the parent for the
|
// buffer; if we're a child, send a request to the parent for the
|
||||||
// shared-memory copy (which it will load if not already available).
|
// shared-memory copy (which it will load if not already available).
|
||||||
if (XRE_IsParentProcess()) {
|
if (XRE_IsParentProcess()) {
|
||||||
UniquePtr<base::SharedMemory> shm =
|
RefPtr<ipc::SharedMemory> shm = LoadFromURI(aURI, &length, precompiled);
|
||||||
LoadFromURI(aURI, &length, precompiled);
|
|
||||||
if (shm) {
|
if (shm) {
|
||||||
mDictSize = length;
|
mDictSize = length;
|
||||||
mDict = AsVariant(std::move(shm));
|
mDict = AsVariant(std::move(shm));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UniquePtr<base::SharedMemory> shm =
|
RefPtr<ipc::SharedMemory> shm = GetHyphDictFromParent(aURI, &length);
|
||||||
GetHyphDictFromParent(aURI, &length);
|
|
||||||
if (shm) {
|
if (shm) {
|
||||||
// We don't need to validate mDict because the parent process
|
// We don't need to validate mDict because the parent process
|
||||||
// will have done so.
|
// will have done so.
|
||||||
@@ -315,7 +312,7 @@ nsHyphenator::nsHyphenator(nsIURI* aURI, bool aHyphenateCapitalized)
|
|||||||
UniquePtr<const CompiledData> data(
|
UniquePtr<const CompiledData> data(
|
||||||
mapped_hyph_compile_file(path.get(), false));
|
mapped_hyph_compile_file(path.get(), false));
|
||||||
if (data) {
|
if (data) {
|
||||||
UniquePtr<base::SharedMemory> shm = CopyToShmem(data.get());
|
RefPtr<ipc::SharedMemory> shm = CopyToShmem(data.get());
|
||||||
if (shm) {
|
if (shm) {
|
||||||
mDictSize = mapped_hyph_compiled_data_size(data.get());
|
mDictSize = mapped_hyph_compiled_data_size(data.get());
|
||||||
mDict = AsVariant(std::move(shm));
|
mDict = AsVariant(std::move(shm));
|
||||||
@@ -337,7 +334,7 @@ nsHyphenator::nsHyphenator(nsIURI* aURI, bool aHyphenateCapitalized)
|
|||||||
bool nsHyphenator::IsValid() {
|
bool nsHyphenator::IsValid() {
|
||||||
return mDict.match(
|
return mDict.match(
|
||||||
[](const void*& ptr) { return ptr != nullptr; },
|
[](const void*& ptr) { return ptr != nullptr; },
|
||||||
[](UniquePtr<base::SharedMemory>& shm) { return shm != nullptr; },
|
[](RefPtr<ipc::SharedMemory>& shm) { return shm != nullptr; },
|
||||||
[](UniquePtr<const HyphDic>& hyph) { return hyph != nullptr; });
|
[](UniquePtr<const HyphDic>& hyph) { return hyph != nullptr; });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,9 +446,9 @@ void nsHyphenator::HyphenateWord(const nsAString& aString, uint32_t aStart,
|
|||||||
static_cast<const uint8_t*>(ptr), mDictSize, utf8.BeginReading(),
|
static_cast<const uint8_t*>(ptr), mDictSize, utf8.BeginReading(),
|
||||||
utf8.Length(), hyphenValues.Elements(), hyphenValues.Length());
|
utf8.Length(), hyphenValues.Elements(), hyphenValues.Length());
|
||||||
},
|
},
|
||||||
[&](UniquePtr<base::SharedMemory>& shm) {
|
[&](RefPtr<ipc::SharedMemory>& shm) {
|
||||||
return mapped_hyph_find_hyphen_values_raw(
|
return mapped_hyph_find_hyphen_values_raw(
|
||||||
static_cast<const uint8_t*>(shm->memory()), mDictSize,
|
static_cast<const uint8_t*>(shm->Memory()), mDictSize,
|
||||||
utf8.BeginReading(), utf8.Length(), hyphenValues.Elements(),
|
utf8.BeginReading(), utf8.Length(), hyphenValues.Elements(),
|
||||||
hyphenValues.Length());
|
hyphenValues.Length());
|
||||||
},
|
},
|
||||||
@@ -489,14 +486,14 @@ void nsHyphenator::HyphenateWord(const nsAString& aString, uint32_t aStart,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsHyphenator::CloneHandle(base::SharedMemoryHandle* aOutHandle,
|
void nsHyphenator::CloneHandle(ipc::SharedMemory::Handle* aOutHandle,
|
||||||
uint32_t* aOutSize) {
|
uint32_t* aOutSize) {
|
||||||
// If the resource is invalid, or if we fail to share it to the child
|
// If the resource is invalid, or if we fail to share it to the child
|
||||||
// process, we'll just bail out and continue without hyphenation; no need
|
// process, we'll just bail out and continue without hyphenation; no need
|
||||||
// for this to be a fatal error.
|
// for this to be a fatal error.
|
||||||
if (!mDict.is<UniquePtr<base::SharedMemory>>()) {
|
if (!mDict.is<RefPtr<ipc::SharedMemory>>()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*aOutHandle = mDict.as<UniquePtr<base::SharedMemory>>()->CloneHandle();
|
*aOutHandle = mDict.as<RefPtr<ipc::SharedMemory>>()->CloneHandle();
|
||||||
*aOutSize = mDictSize;
|
*aOutSize = mDictSize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
#ifndef nsHyphenator_h__
|
#ifndef nsHyphenator_h__
|
||||||
#define nsHyphenator_h__
|
#define nsHyphenator_h__
|
||||||
|
|
||||||
#include "base/shared_memory.h"
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
#include "mozilla/Variant.h"
|
#include "mozilla/Variant.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
@@ -41,7 +42,8 @@ class nsHyphenator {
|
|||||||
|
|
||||||
nsresult Hyphenate(const nsAString& aText, nsTArray<bool>& aHyphens);
|
nsresult Hyphenate(const nsAString& aText, nsTArray<bool>& aHyphens);
|
||||||
|
|
||||||
void CloneHandle(base::SharedMemoryHandle* aOutHandle, uint32_t* aOutSize);
|
void CloneHandle(mozilla::ipc::SharedMemory::Handle* aOutHandle,
|
||||||
|
uint32_t* aOutSize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~nsHyphenator() = default;
|
~nsHyphenator() = default;
|
||||||
@@ -50,8 +52,8 @@ class nsHyphenator {
|
|||||||
nsTArray<bool>& aHyphens);
|
nsTArray<bool>& aHyphens);
|
||||||
|
|
||||||
mozilla::Variant<const void*, // raw pointer to uncompressed omnijar data
|
mozilla::Variant<const void*, // raw pointer to uncompressed omnijar data
|
||||||
mozilla::UniquePtr<base::SharedMemory>, // shmem block
|
RefPtr<mozilla::ipc::SharedMemory>, // shmem block
|
||||||
mozilla::UniquePtr<const HyphDic> // loaded by mapped_hyph
|
mozilla::UniquePtr<const HyphDic> // loaded by mapped_hyph
|
||||||
>
|
>
|
||||||
mDict;
|
mDict;
|
||||||
uint32_t mDictSize; // size of mDict data (not used if type is HyphDic)
|
uint32_t mDictSize; // size of mDict data (not used if type is HyphDic)
|
||||||
|
|||||||
@@ -8,14 +8,12 @@
|
|||||||
|
|
||||||
%{C++
|
%{C++
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
class ContentParent;
|
class ContentParent;
|
||||||
}
|
}
|
||||||
namespace ipc {
|
|
||||||
class FileDescriptor;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define Contractid and CID
|
// Define Contractid and CID
|
||||||
@@ -29,7 +27,7 @@ class FileDescriptor;
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
[ptr] native ContentParent(mozilla::dom::ContentParent);
|
[ptr] native ContentParent(mozilla::dom::ContentParent);
|
||||||
[ref] native FileDescriptor(mozilla::ipc::FileDescriptor);
|
[ref] native SharedMemoryHandle(mozilla::ipc::SharedMemoryHandle);
|
||||||
native MallocSizeOf(mozilla::MallocSizeOf);
|
native MallocSizeOf(mozilla::MallocSizeOf);
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(D85A17C2-AA7C-11d2-9B8C-00805F8A16D9)]
|
[scriptable, builtinclass, uuid(D85A17C2-AA7C-11d2-9B8C-00805F8A16D9)]
|
||||||
@@ -106,6 +104,6 @@ interface nsIStringBundleService : nsISupports
|
|||||||
[notxpcom, nostdcall] void sendContentBundles(in ContentParent aContentParent);
|
[notxpcom, nostdcall] void sendContentBundles(in ContentParent aContentParent);
|
||||||
|
|
||||||
[notxpcom, nostdcall] void registerContentBundle(in ACString aBundleURL,
|
[notxpcom, nostdcall] void registerContentBundle(in ACString aBundleURL,
|
||||||
[const] in FileDescriptor aMapFile,
|
[const] in SharedMemoryHandle aMapHandle,
|
||||||
in size_t aMapSize);
|
in size_t aMapSize);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -209,7 +209,8 @@ class SharedStringBundle final : public nsStringBundleBase {
|
|||||||
* called in child processes, for bundles initially created in the parent
|
* called in child processes, for bundles initially created in the parent
|
||||||
* process.
|
* process.
|
||||||
*/
|
*/
|
||||||
void SetMapFile(const FileDescriptor& aFile, size_t aSize);
|
void SetMapFile(const mozilla::ipc::SharedMemoryHandle& aHandle,
|
||||||
|
size_t aSize);
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(SHAREDSTRINGBUNDLE_IID)
|
NS_DECLARE_STATIC_IID_ACCESSOR(SHAREDSTRINGBUNDLE_IID)
|
||||||
@@ -222,16 +223,16 @@ class SharedStringBundle final : public nsStringBundleBase {
|
|||||||
* parent process, and may be used to send shared string bundles to child
|
* parent process, and may be used to send shared string bundles to child
|
||||||
* processes.
|
* processes.
|
||||||
*/
|
*/
|
||||||
FileDescriptor CloneFileDescriptor() const {
|
mozilla::ipc::SharedMemoryHandle CloneHandle() const {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
if (mMapFile.isSome()) {
|
if (mMapHandle.isSome()) {
|
||||||
return mMapFile.ref();
|
return mozilla::ipc::SharedMemory::CloneHandle(mMapHandle.ref());
|
||||||
}
|
}
|
||||||
return mStringMap->CloneFileDescriptor();
|
return mStringMap->CloneHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MapSize() const {
|
size_t MapSize() const {
|
||||||
if (mMapFile.isSome()) {
|
if (mMapHandle.isSome()) {
|
||||||
return mMapSize;
|
return mMapSize;
|
||||||
}
|
}
|
||||||
if (mStringMap) {
|
if (mStringMap) {
|
||||||
@@ -240,14 +241,14 @@ class SharedStringBundle final : public nsStringBundleBase {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Initialized() const { return mStringMap || mMapFile.isSome(); }
|
bool Initialized() const { return mStringMap || mMapHandle.isSome(); }
|
||||||
|
|
||||||
StringBundleDescriptor GetDescriptor() const {
|
StringBundleDescriptor GetDescriptor() const {
|
||||||
MOZ_ASSERT(Initialized());
|
MOZ_ASSERT(Initialized());
|
||||||
|
|
||||||
StringBundleDescriptor descriptor;
|
StringBundleDescriptor descriptor;
|
||||||
descriptor.bundleURL() = BundleURL();
|
descriptor.bundleURL() = BundleURL();
|
||||||
descriptor.mapFile() = CloneFileDescriptor();
|
descriptor.mapHandle() = CloneHandle();
|
||||||
descriptor.mapSize() = MapSize();
|
descriptor.mapSize() = MapSize();
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
@@ -273,7 +274,7 @@ class SharedStringBundle final : public nsStringBundleBase {
|
|||||||
private:
|
private:
|
||||||
RefPtr<SharedStringMap> mStringMap;
|
RefPtr<SharedStringMap> mStringMap;
|
||||||
|
|
||||||
Maybe<FileDescriptor> mMapFile;
|
Maybe<mozilla::ipc::SharedMemoryHandle> mMapHandle;
|
||||||
size_t mMapSize;
|
size_t mMapSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -521,9 +522,9 @@ nsresult nsStringBundle::LoadProperties() {
|
|||||||
nsresult SharedStringBundle::LoadProperties() {
|
nsresult SharedStringBundle::LoadProperties() {
|
||||||
if (mStringMap) return NS_OK;
|
if (mStringMap) return NS_OK;
|
||||||
|
|
||||||
if (mMapFile.isSome()) {
|
if (mMapHandle.isSome()) {
|
||||||
mStringMap = new SharedStringMap(mMapFile.ref(), mMapSize);
|
mStringMap = new SharedStringMap(mMapHandle.ref(), mMapSize);
|
||||||
mMapFile.reset();
|
mMapHandle.reset();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,10 +577,11 @@ nsresult SharedStringBundle::LoadProperties() {
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedStringBundle::SetMapFile(const FileDescriptor& aFile, size_t aSize) {
|
void SharedStringBundle::SetMapFile(
|
||||||
|
const mozilla::ipc::SharedMemoryHandle& aHandle, size_t aSize) {
|
||||||
MOZ_ASSERT(XRE_IsContentProcess());
|
MOZ_ASSERT(XRE_IsContentProcess());
|
||||||
mStringMap = nullptr;
|
mStringMap = nullptr;
|
||||||
mMapFile.emplace(aFile);
|
mMapHandle.emplace(mozilla::ipc::SharedMemory::CloneHandle(aHandle));
|
||||||
mMapSize = aSize;
|
mMapSize = aSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,8 +829,8 @@ void nsStringBundleService::SendContentBundles(ContentParent* aContentParent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void nsStringBundleService::RegisterContentBundle(
|
void nsStringBundleService::RegisterContentBundle(
|
||||||
const nsACString& aBundleURL, const FileDescriptor& aMapFile,
|
const nsACString& aBundleURL,
|
||||||
size_t aMapSize) {
|
const mozilla::ipc::SharedMemoryHandle& aMapHandle, size_t aMapSize) {
|
||||||
RefPtr<StringBundleProxy> proxy;
|
RefPtr<StringBundleProxy> proxy;
|
||||||
|
|
||||||
bundleCacheEntry_t* cacheEntry = mBundleMap.Get(aBundleURL);
|
bundleCacheEntry_t* cacheEntry = mBundleMap.Get(aBundleURL);
|
||||||
@@ -846,7 +848,7 @@ void nsStringBundleService::RegisterContentBundle(
|
|||||||
|
|
||||||
auto bundle = MakeBundleRefPtr<SharedStringBundle>(
|
auto bundle = MakeBundleRefPtr<SharedStringBundle>(
|
||||||
PromiseFlatCString(aBundleURL).get());
|
PromiseFlatCString(aBundleURL).get());
|
||||||
bundle->SetMapFile(aMapFile, aMapSize);
|
bundle->SetMapFile(aMapHandle, aMapSize);
|
||||||
|
|
||||||
if (proxy) {
|
if (proxy) {
|
||||||
proxy->Retarget(bundle);
|
proxy->Retarget(bundle);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "mozilla/ipc/BigBuffer.h"
|
#include "mozilla/ipc/BigBuffer.h"
|
||||||
|
|
||||||
|
#include "chrome/common/ipc_message_utils.h"
|
||||||
#include "mozilla/ipc/SharedMemory.h"
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ void IdleSchedulerChild::Init(IdlePeriodState* aIdlePeriodState) {
|
|||||||
auto resolve =
|
auto resolve =
|
||||||
[&](std::tuple<mozilla::Maybe<SharedMemoryHandle>, uint32_t>&& aResult) {
|
[&](std::tuple<mozilla::Maybe<SharedMemoryHandle>, uint32_t>&& aResult) {
|
||||||
if (std::get<0>(aResult)) {
|
if (std::get<0>(aResult)) {
|
||||||
mActiveCounter.SetHandle(std::move(*std::get<0>(aResult)), false);
|
mActiveCounter->SetHandle(std::move(*std::get<0>(aResult)),
|
||||||
mActiveCounter.Map(sizeof(int32_t));
|
SharedMemory::RightsReadWrite);
|
||||||
|
mActiveCounter->Map(sizeof(int32_t));
|
||||||
mChildId = std::get<1>(aResult);
|
mChildId = std::get<1>(aResult);
|
||||||
if (mChildId && mIdlePeriodState && mIdlePeriodState->IsActive()) {
|
if (mChildId && mIdlePeriodState && mIdlePeriodState->IsActive()) {
|
||||||
SetActive();
|
SetActive();
|
||||||
@@ -53,23 +54,23 @@ IPCResult IdleSchedulerChild::RecvIdleTime(uint64_t aId, TimeDuration aBudget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IdleSchedulerChild::SetActive() {
|
void IdleSchedulerChild::SetActive() {
|
||||||
if (mChildId && CanSend() && mActiveCounter.memory()) {
|
if (mChildId && CanSend() && mActiveCounter->Memory()) {
|
||||||
++(static_cast<Atomic<int32_t>*>(
|
++(static_cast<Atomic<int32_t>*>(
|
||||||
mActiveCounter.memory())[NS_IDLE_SCHEDULER_INDEX_OF_ACTIVITY_COUNTER]);
|
mActiveCounter->Memory())[NS_IDLE_SCHEDULER_INDEX_OF_ACTIVITY_COUNTER]);
|
||||||
++(static_cast<Atomic<int32_t>*>(mActiveCounter.memory())[mChildId]);
|
++(static_cast<Atomic<int32_t>*>(mActiveCounter->Memory())[mChildId]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IdleSchedulerChild::SetPaused() {
|
bool IdleSchedulerChild::SetPaused() {
|
||||||
if (mChildId && CanSend() && mActiveCounter.memory()) {
|
if (mChildId && CanSend() && mActiveCounter->Memory()) {
|
||||||
--(static_cast<Atomic<int32_t>*>(mActiveCounter.memory())[mChildId]);
|
--(static_cast<Atomic<int32_t>*>(mActiveCounter->Memory())[mChildId]);
|
||||||
// The following expression reduces the global activity count and checks if
|
// The following expression reduces the global activity count and checks if
|
||||||
// it drops below the cpu counter limit.
|
// it drops below the cpu counter limit.
|
||||||
return (static_cast<Atomic<int32_t>*>(
|
return (static_cast<Atomic<int32_t>*>(mActiveCounter->Memory())
|
||||||
mActiveCounter
|
[NS_IDLE_SCHEDULER_INDEX_OF_ACTIVITY_COUNTER])-- ==
|
||||||
.memory())[NS_IDLE_SCHEDULER_INDEX_OF_ACTIVITY_COUNTER])-- ==
|
|
||||||
static_cast<Atomic<int32_t>*>(
|
static_cast<Atomic<int32_t>*>(
|
||||||
mActiveCounter.memory())[NS_IDLE_SCHEDULER_INDEX_OF_CPU_COUNTER];
|
mActiveCounter
|
||||||
|
->Memory())[NS_IDLE_SCHEDULER_INDEX_OF_CPU_COUNTER];
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/ipc/PIdleSchedulerChild.h"
|
#include "mozilla/ipc/PIdleSchedulerChild.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
|
|
||||||
class nsIIdlePeriod;
|
class nsIIdlePeriod;
|
||||||
|
|
||||||
@@ -56,7 +58,7 @@ class IdleSchedulerChild final : public PIdleSchedulerChild {
|
|||||||
friend class BackgroundChildImpl;
|
friend class BackgroundChildImpl;
|
||||||
|
|
||||||
// See IdleScheduleParent::sActiveChildCounter
|
// See IdleScheduleParent::sActiveChildCounter
|
||||||
base::SharedMemory mActiveCounter;
|
RefPtr<SharedMemory> mActiveCounter = MakeRefPtr<SharedMemory>();
|
||||||
|
|
||||||
IdlePeriodState* mIdlePeriodState = nullptr;
|
IdlePeriodState* mIdlePeriodState = nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
namespace mozilla::ipc {
|
namespace mozilla::ipc {
|
||||||
|
|
||||||
base::SharedMemory* IdleSchedulerParent::sActiveChildCounter = nullptr;
|
RefPtr<SharedMemory> IdleSchedulerParent::sActiveChildCounter = nullptr;
|
||||||
std::bitset<NS_IDLE_SCHEDULER_COUNTER_ARRAY_LENGHT>
|
std::bitset<NS_IDLE_SCHEDULER_COUNTER_ARRAY_LENGHT>
|
||||||
IdleSchedulerParent::sInUseChildCounters;
|
IdleSchedulerParent::sInUseChildCounters;
|
||||||
LinkedList<IdleSchedulerParent> IdleSchedulerParent::sIdleAndGCRequests;
|
LinkedList<IdleSchedulerParent> IdleSchedulerParent::sIdleAndGCRequests;
|
||||||
@@ -107,9 +107,9 @@ void IdleSchedulerParent::CalculateNumIdleTasks() {
|
|||||||
std::min(std::max(sNumCPUs / sPrefConcurrentGCsCPUDivisor, 1u),
|
std::min(std::max(sNumCPUs / sPrefConcurrentGCsCPUDivisor, 1u),
|
||||||
sPrefConcurrentGCsMax);
|
sPrefConcurrentGCsMax);
|
||||||
|
|
||||||
if (sActiveChildCounter && sActiveChildCounter->memory()) {
|
if (sActiveChildCounter && sActiveChildCounter->Memory()) {
|
||||||
static_cast<Atomic<int32_t>*>(
|
static_cast<Atomic<int32_t>*>(
|
||||||
sActiveChildCounter->memory())[NS_IDLE_SCHEDULER_INDEX_OF_CPU_COUNTER] =
|
sActiveChildCounter->Memory())[NS_IDLE_SCHEDULER_INDEX_OF_CPU_COUNTER] =
|
||||||
static_cast<int32_t>(sMaxConcurrentIdleTasksInChildProcesses);
|
static_cast<int32_t>(sMaxConcurrentIdleTasksInChildProcesses);
|
||||||
}
|
}
|
||||||
IdleSchedulerParent::Schedule(nullptr);
|
IdleSchedulerParent::Schedule(nullptr);
|
||||||
@@ -120,13 +120,13 @@ IdleSchedulerParent::~IdleSchedulerParent() {
|
|||||||
// that is the case.
|
// that is the case.
|
||||||
if (mChildId) {
|
if (mChildId) {
|
||||||
sInUseChildCounters[mChildId] = false;
|
sInUseChildCounters[mChildId] = false;
|
||||||
if (sActiveChildCounter && sActiveChildCounter->memory() &&
|
if (sActiveChildCounter && sActiveChildCounter->Memory() &&
|
||||||
static_cast<Atomic<int32_t>*>(
|
static_cast<Atomic<int32_t>*>(
|
||||||
sActiveChildCounter->memory())[mChildId]) {
|
sActiveChildCounter->Memory())[mChildId]) {
|
||||||
--static_cast<Atomic<int32_t>*>(
|
--static_cast<Atomic<int32_t>*>(
|
||||||
sActiveChildCounter
|
sActiveChildCounter
|
||||||
->memory())[NS_IDLE_SCHEDULER_INDEX_OF_ACTIVITY_COUNTER];
|
->Memory())[NS_IDLE_SCHEDULER_INDEX_OF_ACTIVITY_COUNTER];
|
||||||
static_cast<Atomic<int32_t>*>(sActiveChildCounter->memory())[mChildId] =
|
static_cast<Atomic<int32_t>*>(sActiveChildCounter->Memory())[mChildId] =
|
||||||
0;
|
0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,6 @@ IdleSchedulerParent::~IdleSchedulerParent() {
|
|||||||
sChildProcessesAlive--;
|
sChildProcessesAlive--;
|
||||||
if (sChildProcessesAlive == 0) {
|
if (sChildProcessesAlive == 0) {
|
||||||
MOZ_ASSERT(sIdleAndGCRequests.isEmpty());
|
MOZ_ASSERT(sIdleAndGCRequests.isEmpty());
|
||||||
delete sActiveChildCounter;
|
|
||||||
sActiveChildCounter = nullptr;
|
sActiveChildCounter = nullptr;
|
||||||
|
|
||||||
if (sStarvationPreventer) {
|
if (sStarvationPreventer) {
|
||||||
@@ -178,24 +177,23 @@ IPCResult IdleSchedulerParent::RecvInitForIdleUse(
|
|||||||
// Create a shared memory object which is shared across all the relevant
|
// Create a shared memory object which is shared across all the relevant
|
||||||
// processes.
|
// processes.
|
||||||
if (!sActiveChildCounter) {
|
if (!sActiveChildCounter) {
|
||||||
sActiveChildCounter = new base::SharedMemory();
|
sActiveChildCounter = MakeRefPtr<SharedMemory>();
|
||||||
size_t shmemSize = NS_IDLE_SCHEDULER_COUNTER_ARRAY_LENGHT * sizeof(int32_t);
|
size_t shmemSize = NS_IDLE_SCHEDULER_COUNTER_ARRAY_LENGHT * sizeof(int32_t);
|
||||||
if (sActiveChildCounter->Create(shmemSize) &&
|
if (sActiveChildCounter->Create(shmemSize) &&
|
||||||
sActiveChildCounter->Map(shmemSize)) {
|
sActiveChildCounter->Map(shmemSize)) {
|
||||||
memset(sActiveChildCounter->memory(), 0, shmemSize);
|
memset(sActiveChildCounter->Memory(), 0, shmemSize);
|
||||||
sInUseChildCounters[NS_IDLE_SCHEDULER_INDEX_OF_ACTIVITY_COUNTER] = true;
|
sInUseChildCounters[NS_IDLE_SCHEDULER_INDEX_OF_ACTIVITY_COUNTER] = true;
|
||||||
sInUseChildCounters[NS_IDLE_SCHEDULER_INDEX_OF_CPU_COUNTER] = true;
|
sInUseChildCounters[NS_IDLE_SCHEDULER_INDEX_OF_CPU_COUNTER] = true;
|
||||||
static_cast<Atomic<int32_t>*>(
|
static_cast<Atomic<int32_t>*>(
|
||||||
sActiveChildCounter
|
sActiveChildCounter
|
||||||
->memory())[NS_IDLE_SCHEDULER_INDEX_OF_CPU_COUNTER] =
|
->Memory())[NS_IDLE_SCHEDULER_INDEX_OF_CPU_COUNTER] =
|
||||||
static_cast<int32_t>(sMaxConcurrentIdleTasksInChildProcesses);
|
static_cast<int32_t>(sMaxConcurrentIdleTasksInChildProcesses);
|
||||||
} else {
|
} else {
|
||||||
delete sActiveChildCounter;
|
|
||||||
sActiveChildCounter = nullptr;
|
sActiveChildCounter = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Maybe<SharedMemoryHandle> activeCounter;
|
Maybe<SharedMemory::Handle> activeCounter;
|
||||||
if (SharedMemoryHandle handle =
|
if (SharedMemory::Handle handle =
|
||||||
sActiveChildCounter ? sActiveChildCounter->CloneHandle() : nullptr) {
|
sActiveChildCounter ? sActiveChildCounter->CloneHandle() : nullptr) {
|
||||||
activeCounter.emplace(std::move(handle));
|
activeCounter.emplace(std::move(handle));
|
||||||
}
|
}
|
||||||
@@ -212,7 +210,7 @@ IPCResult IdleSchedulerParent::RecvInitForIdleUse(
|
|||||||
// If there wasn't an empty item, we'll fallback to 0.
|
// If there wasn't an empty item, we'll fallback to 0.
|
||||||
mChildId = unusedId;
|
mChildId = unusedId;
|
||||||
|
|
||||||
aResolve(std::tuple<mozilla::Maybe<SharedMemoryHandle>&&, const uint32_t&>(
|
aResolve(std::tuple<mozilla::Maybe<SharedMemory::Handle>&&, const uint32_t&>(
|
||||||
std::move(activeCounter), mChildId));
|
std::move(activeCounter), mChildId));
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
@@ -322,7 +320,7 @@ int32_t IdleSchedulerParent::ActiveCount() {
|
|||||||
if (sActiveChildCounter) {
|
if (sActiveChildCounter) {
|
||||||
return (static_cast<Atomic<int32_t>*>(
|
return (static_cast<Atomic<int32_t>*>(
|
||||||
sActiveChildCounter
|
sActiveChildCounter
|
||||||
->memory())[NS_IDLE_SCHEDULER_INDEX_OF_ACTIVITY_COUNTER]);
|
->Memory())[NS_IDLE_SCHEDULER_INDEX_OF_ACTIVITY_COUNTER]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,9 @@
|
|||||||
#include "mozilla/Atomics.h"
|
#include "mozilla/Atomics.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/LinkedList.h"
|
#include "mozilla/LinkedList.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/ipc/PIdleSchedulerParent.h"
|
#include "mozilla/ipc/PIdleSchedulerParent.h"
|
||||||
#include "base/shared_memory.h"
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
#define NS_IDLE_SCHEDULER_COUNTER_ARRAY_LENGHT 1024
|
#define NS_IDLE_SCHEDULER_COUNTER_ARRAY_LENGHT 1024
|
||||||
@@ -88,7 +89,7 @@ class IdleSchedulerParent final
|
|||||||
// This way the global activity can be checked in a fast way by just looking
|
// This way the global activity can be checked in a fast way by just looking
|
||||||
// at [0] value.
|
// at [0] value.
|
||||||
// [1] is used for cpu count for child processes.
|
// [1] is used for cpu count for child processes.
|
||||||
static base::SharedMemory* sActiveChildCounter;
|
static RefPtr<SharedMemory> sActiveChildCounter;
|
||||||
// A bit is set if there is a child with child Id as the offset.
|
// A bit is set if there is a child with child Id as the offset.
|
||||||
// The bit is used to check per child specific activity counters in
|
// The bit is used to check per child specific activity counters in
|
||||||
// sActiveChildCounter.
|
// sActiveChildCounter.
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* 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
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
include protocol PBackground;
|
include protocol PBackground;
|
||||||
using mozilla::TimeDuration from "mozilla/TimeStamp.h";
|
using mozilla::TimeDuration from "mozilla/TimeStamp.h";
|
||||||
[MoveOnly] using base::SharedMemoryHandle from "base/shared_memory.h";
|
[MoveOnly] using mozilla::ipc::SharedMemoryHandle from "mozilla/ipc/SharedMemory.h";
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
@@ -32,8 +32,7 @@ namespace ipc {
|
|||||||
* process, child process informs the scheduler and the process is moved back
|
* process, child process informs the scheduler and the process is moved back
|
||||||
* to the default queue.
|
* to the default queue.
|
||||||
*/
|
*/
|
||||||
async protocol PIdleScheduler
|
async protocol PIdleScheduler {
|
||||||
{
|
|
||||||
manager PBackground;
|
manager PBackground;
|
||||||
|
|
||||||
child:
|
child:
|
||||||
@@ -44,8 +43,8 @@ parent:
|
|||||||
async RequestIdleTime(uint64_t id, TimeDuration budget);
|
async RequestIdleTime(uint64_t id, TimeDuration budget);
|
||||||
async IdleTimeUsed(uint64_t id);
|
async IdleTimeUsed(uint64_t id);
|
||||||
|
|
||||||
// Child can send explicit Schedule message to parent if it thinks parent process
|
// Child can send explicit Schedule message to parent if it thinks parent
|
||||||
// might be able to let some other process to use idle time.
|
// process might be able to let some other process to use idle time.
|
||||||
async Schedule();
|
async Schedule();
|
||||||
|
|
||||||
// Note, these two messages can be sent even before InitForIdleUse.
|
// Note, these two messages can be sent even before InitForIdleUse.
|
||||||
@@ -53,7 +52,7 @@ parent:
|
|||||||
async PrioritizedOperationDone();
|
async PrioritizedOperationDone();
|
||||||
|
|
||||||
// Ask if now would be a good time to GC
|
// Ask if now would be a good time to GC
|
||||||
async RequestGC() returns (bool may_gc);
|
async RequestGC() returns(bool may_gc);
|
||||||
|
|
||||||
// Let the parent know when we start a GC without asking first.
|
// Let the parent know when we start a GC without asking first.
|
||||||
async StartedGC();
|
async StartedGC();
|
||||||
@@ -61,10 +60,10 @@ parent:
|
|||||||
// Called for ending any kind of GC.
|
// Called for ending any kind of GC.
|
||||||
async DoneGC();
|
async DoneGC();
|
||||||
|
|
||||||
// This message is never sent. Each PIdleScheduler actor will stay alive as long as
|
// This message is never sent. Each PIdleScheduler actor will stay alive as
|
||||||
// its PBackground manager.
|
// long as its PBackground manager.
|
||||||
async __delete__();
|
async __delete__();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ void ProcessChild::AddPlatformBuildID(geckoargs::ChildProcessArgs& aExtraArgs) {
|
|||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
bool ProcessChild::InitPrefs(int aArgc, char* aArgv[]) {
|
bool ProcessChild::InitPrefs(int aArgc, char* aArgv[]) {
|
||||||
Maybe<UniqueFileHandle> prefsHandle =
|
Maybe<SharedMemoryHandle> prefsHandle =
|
||||||
geckoargs::sPrefsHandle.Get(aArgc, aArgv);
|
geckoargs::sPrefsHandle.Get(aArgc, aArgv);
|
||||||
Maybe<UniqueFileHandle> prefMapHandle =
|
Maybe<SharedMemoryHandle> prefMapHandle =
|
||||||
geckoargs::sPrefMapHandle.Get(aArgc, aArgv);
|
geckoargs::sPrefMapHandle.Get(aArgc, aArgv);
|
||||||
Maybe<uint64_t> prefsLen = geckoargs::sPrefsLen.Get(aArgc, aArgv);
|
Maybe<uint64_t> prefsLen = geckoargs::sPrefsLen.Get(aArgc, aArgv);
|
||||||
Maybe<uint64_t> prefMapSize = geckoargs::sPrefMapSize.Get(aArgc, aArgv);
|
Maybe<uint64_t> prefMapSize = geckoargs::sPrefMapSize.Get(aArgc, aArgv);
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
|
|
||||||
#include "mozilla/GeckoArgs.h"
|
#include "mozilla/GeckoArgs.h"
|
||||||
#include "mozilla/ipc/FileDescriptor.h"
|
#include "mozilla/ipc/FileDescriptor.h"
|
||||||
#include "base/shared_memory.h"
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@@ -38,9 +39,9 @@ class SharedPreferenceSerializer final {
|
|||||||
size_t GetPrefMapSize() const { return mPrefMapSize; }
|
size_t GetPrefMapSize() const { return mPrefMapSize; }
|
||||||
size_t GetPrefsLength() const { return mPrefsLength; }
|
size_t GetPrefsLength() const { return mPrefsLength; }
|
||||||
|
|
||||||
const UniqueFileHandle& GetPrefsHandle() const { return mPrefsHandle; }
|
const SharedMemoryHandle& GetPrefsHandle() const { return mPrefsHandle; }
|
||||||
|
|
||||||
const UniqueFileHandle& GetPrefMapHandle() const { return mPrefMapHandle; }
|
const SharedMemoryHandle& GetPrefMapHandle() const { return mPrefMapHandle; }
|
||||||
|
|
||||||
void AddSharedPrefCmdLineArgs(GeckoChildProcessHost& procHost,
|
void AddSharedPrefCmdLineArgs(GeckoChildProcessHost& procHost,
|
||||||
geckoargs::ChildProcessArgs& aExtraOpts) const;
|
geckoargs::ChildProcessArgs& aExtraOpts) const;
|
||||||
@@ -49,8 +50,8 @@ class SharedPreferenceSerializer final {
|
|||||||
DISALLOW_COPY_AND_ASSIGN(SharedPreferenceSerializer);
|
DISALLOW_COPY_AND_ASSIGN(SharedPreferenceSerializer);
|
||||||
size_t mPrefMapSize;
|
size_t mPrefMapSize;
|
||||||
size_t mPrefsLength;
|
size_t mPrefsLength;
|
||||||
UniqueFileHandle mPrefMapHandle;
|
SharedMemoryHandle mPrefMapHandle;
|
||||||
UniqueFileHandle mPrefsHandle;
|
SharedMemoryHandle mPrefsHandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SharedPreferenceDeserializer final {
|
class SharedPreferenceDeserializer final {
|
||||||
@@ -58,18 +59,18 @@ class SharedPreferenceDeserializer final {
|
|||||||
SharedPreferenceDeserializer();
|
SharedPreferenceDeserializer();
|
||||||
~SharedPreferenceDeserializer();
|
~SharedPreferenceDeserializer();
|
||||||
|
|
||||||
bool DeserializeFromSharedMemory(UniqueFileHandle aPrefsHandle,
|
bool DeserializeFromSharedMemory(SharedMemoryHandle aPrefsHandle,
|
||||||
UniqueFileHandle aPrefMapHandle,
|
SharedMemoryHandle aPrefMapHandle,
|
||||||
uint64_t aPrefsLen, uint64_t aPrefMapSize);
|
uint64_t aPrefsLen, uint64_t aPrefMapSize);
|
||||||
|
|
||||||
const FileDescriptor& GetPrefMapHandle() const;
|
const SharedMemoryHandle& GetPrefMapHandle() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(SharedPreferenceDeserializer);
|
DISALLOW_COPY_AND_ASSIGN(SharedPreferenceDeserializer);
|
||||||
Maybe<FileDescriptor> mPrefMapHandle;
|
Maybe<SharedMemoryHandle> mPrefMapHandle;
|
||||||
Maybe<size_t> mPrefsLen;
|
Maybe<size_t> mPrefsLen;
|
||||||
Maybe<size_t> mPrefMapSize;
|
Maybe<size_t> mPrefMapSize;
|
||||||
base::SharedMemory mShmem;
|
RefPtr<SharedMemory> mShmem = MakeRefPtr<SharedMemory>();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate command line argument to spawn a child process. If the shared memory
|
// Generate command line argument to spawn a child process. If the shared memory
|
||||||
@@ -79,7 +80,7 @@ void ExportSharedJSInit(GeckoChildProcessHost& procHost,
|
|||||||
|
|
||||||
// Initialize the content used by the JS engine during the initialization of a
|
// Initialize the content used by the JS engine during the initialization of a
|
||||||
// JS::Runtime.
|
// JS::Runtime.
|
||||||
bool ImportSharedJSInit(UniqueFileHandle aJsInitHandle, uint64_t aJsInitLen);
|
bool ImportSharedJSInit(SharedMemoryHandle aJsInitHandle, uint64_t aJsInitLen);
|
||||||
|
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/GeckoArgs.h"
|
#include "mozilla/GeckoArgs.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/dom/RemoteType.h"
|
#include "mozilla/dom/RemoteType.h"
|
||||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||||
#include "mozilla/UniquePtrExtensions.h"
|
#include "mozilla/UniquePtrExtensions.h"
|
||||||
@@ -39,8 +40,7 @@ SharedPreferenceSerializer::SharedPreferenceSerializer(
|
|||||||
bool SharedPreferenceSerializer::SerializeToSharedMemory(
|
bool SharedPreferenceSerializer::SerializeToSharedMemory(
|
||||||
const GeckoProcessType aDestinationProcessType,
|
const GeckoProcessType aDestinationProcessType,
|
||||||
const nsACString& aDestinationRemoteType) {
|
const nsACString& aDestinationRemoteType) {
|
||||||
mPrefMapHandle =
|
mPrefMapHandle = Preferences::EnsureSnapshot(&mPrefMapSize);
|
||||||
Preferences::EnsureSnapshot(&mPrefMapSize).TakePlatformHandle();
|
|
||||||
|
|
||||||
bool destIsWebContent =
|
bool destIsWebContent =
|
||||||
aDestinationProcessType == GeckoProcessType_Content &&
|
aDestinationProcessType == GeckoProcessType_Content &&
|
||||||
@@ -52,30 +52,31 @@ bool SharedPreferenceSerializer::SerializeToSharedMemory(
|
|||||||
Preferences::SerializePreferences(prefs, destIsWebContent);
|
Preferences::SerializePreferences(prefs, destIsWebContent);
|
||||||
mPrefsLength = prefs.Length();
|
mPrefsLength = prefs.Length();
|
||||||
|
|
||||||
base::SharedMemory shm;
|
RefPtr<SharedMemory> shm = MakeRefPtr<SharedMemory>();
|
||||||
// Set up the shared memory.
|
// Set up the shared memory.
|
||||||
if (!shm.Create(prefs.Length())) {
|
if (!shm->Create(prefs.Length())) {
|
||||||
NS_ERROR("failed to create shared memory in the parent");
|
NS_ERROR("failed to create shared memory in the parent");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!shm.Map(prefs.Length())) {
|
if (!shm->Map(prefs.Length())) {
|
||||||
NS_ERROR("failed to map shared memory in the parent");
|
NS_ERROR("failed to map shared memory in the parent");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the serialized prefs into the shared memory.
|
// Copy the serialized prefs into the shared memory.
|
||||||
memcpy(static_cast<char*>(shm.memory()), prefs.get(), mPrefsLength);
|
memcpy(static_cast<char*>(shm->Memory()), prefs.get(), mPrefsLength);
|
||||||
|
|
||||||
mPrefsHandle = shm.TakeHandle();
|
mPrefsHandle = shm->TakeHandleAndUnmap();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedPreferenceSerializer::AddSharedPrefCmdLineArgs(
|
void SharedPreferenceSerializer::AddSharedPrefCmdLineArgs(
|
||||||
mozilla::ipc::GeckoChildProcessHost& procHost,
|
mozilla::ipc::GeckoChildProcessHost& procHost,
|
||||||
geckoargs::ChildProcessArgs& aExtraOpts) const {
|
geckoargs::ChildProcessArgs& aExtraOpts) const {
|
||||||
UniqueFileHandle prefsHandle = DuplicateFileHandle(GetPrefsHandle());
|
SharedMemoryHandle prefsHandle = SharedMemory::CloneHandle(GetPrefsHandle());
|
||||||
MOZ_RELEASE_ASSERT(prefsHandle, "failed to duplicate prefs handle");
|
MOZ_RELEASE_ASSERT(prefsHandle, "failed to duplicate prefs handle");
|
||||||
UniqueFileHandle prefMapHandle = DuplicateFileHandle(GetPrefMapHandle());
|
SharedMemoryHandle prefMapHandle =
|
||||||
|
SharedMemory::CloneHandle(GetPrefMapHandle());
|
||||||
MOZ_RELEASE_ASSERT(prefMapHandle, "failed to duplicate pref map handle");
|
MOZ_RELEASE_ASSERT(prefMapHandle, "failed to duplicate pref map handle");
|
||||||
|
|
||||||
// Pass the handles and lengths via command line flags.
|
// Pass the handles and lengths via command line flags.
|
||||||
@@ -94,7 +95,7 @@ SharedPreferenceDeserializer::~SharedPreferenceDeserializer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SharedPreferenceDeserializer::DeserializeFromSharedMemory(
|
bool SharedPreferenceDeserializer::DeserializeFromSharedMemory(
|
||||||
UniqueFileHandle aPrefsHandle, UniqueFileHandle aPrefMapHandle,
|
SharedMemoryHandle aPrefsHandle, SharedMemoryHandle aPrefMapHandle,
|
||||||
uint64_t aPrefsLen, uint64_t aPrefMapSize) {
|
uint64_t aPrefsLen, uint64_t aPrefMapSize) {
|
||||||
if (!aPrefsHandle || !aPrefMapHandle || !aPrefsLen || !aPrefMapSize) {
|
if (!aPrefsHandle || !aPrefMapHandle || !aPrefsLen || !aPrefMapSize) {
|
||||||
return false;
|
return false;
|
||||||
@@ -111,21 +112,23 @@ bool SharedPreferenceDeserializer::DeserializeFromSharedMemory(
|
|||||||
Preferences::InitSnapshot(mPrefMapHandle.ref(), *mPrefMapSize);
|
Preferences::InitSnapshot(mPrefMapHandle.ref(), *mPrefMapSize);
|
||||||
|
|
||||||
// Set up early prefs from the shared memory.
|
// Set up early prefs from the shared memory.
|
||||||
if (!mShmem.SetHandle(std::move(aPrefsHandle), /* read_only */ true)) {
|
if (!mShmem->SetHandle(std::move(aPrefsHandle),
|
||||||
|
SharedMemory::RightsReadOnly)) {
|
||||||
NS_ERROR("failed to open shared memory in the child");
|
NS_ERROR("failed to open shared memory in the child");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!mShmem.Map(*mPrefsLen)) {
|
if (!mShmem->Map(*mPrefsLen)) {
|
||||||
NS_ERROR("failed to map shared memory in the child");
|
NS_ERROR("failed to map shared memory in the child");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Preferences::DeserializePreferences(static_cast<char*>(mShmem.memory()),
|
Preferences::DeserializePreferences(static_cast<char*>(mShmem->Memory()),
|
||||||
*mPrefsLen);
|
*mPrefsLen);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FileDescriptor& SharedPreferenceDeserializer::GetPrefMapHandle() const {
|
const SharedMemoryHandle& SharedPreferenceDeserializer::GetPrefMapHandle()
|
||||||
|
const {
|
||||||
MOZ_ASSERT(mPrefMapHandle.isSome());
|
MOZ_ASSERT(mPrefMapHandle.isSome());
|
||||||
|
|
||||||
return mPrefMapHandle.ref();
|
return mPrefMapHandle.ref();
|
||||||
@@ -138,12 +141,12 @@ void ExportSharedJSInit(mozilla::ipc::GeckoChildProcessHost& procHost,
|
|||||||
return;
|
return;
|
||||||
#else
|
#else
|
||||||
auto& shmem = xpc::SelfHostedShmem::GetSingleton();
|
auto& shmem = xpc::SelfHostedShmem::GetSingleton();
|
||||||
UniqueFileHandle handle = DuplicateFileHandle(shmem.Handle());
|
SharedMemoryHandle handle = SharedMemory::CloneHandle(shmem.Handle());
|
||||||
size_t len = shmem.Content().Length();
|
size_t len = shmem.Content().Length();
|
||||||
|
|
||||||
// If the file is not found or the content is empty, then we would start the
|
// If the file is not found or the content is empty, then we would start the
|
||||||
// content process without this optimization.
|
// content process without this optimization.
|
||||||
if (!handle || !len) {
|
if (!SharedMemory::IsHandleValid(handle) || !len) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +156,7 @@ void ExportSharedJSInit(mozilla::ipc::GeckoChildProcessHost& procHost,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImportSharedJSInit(UniqueFileHandle aJsInitHandle, uint64_t aJsInitLen) {
|
bool ImportSharedJSInit(SharedMemoryHandle aJsInitHandle, uint64_t aJsInitLen) {
|
||||||
// This is an optimization, and as such we can safely recover if the command
|
// This is an optimization, and as such we can safely recover if the command
|
||||||
// line argument are not provided.
|
// line argument are not provided.
|
||||||
if (!aJsInitLen || !aJsInitHandle) {
|
if (!aJsInitLen || !aJsInitHandle) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#ifndef MOZILLA_IPC_RAWSHMEM_H_
|
#ifndef MOZILLA_IPC_RAWSHMEM_H_
|
||||||
#define MOZILLA_IPC_RAWSHMEM_H_
|
#define MOZILLA_IPC_RAWSHMEM_H_
|
||||||
|
|
||||||
|
#include "chrome/common/ipc_message_utils.h"
|
||||||
#include "mozilla/ipc/SharedMemory.h"
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "mozilla/Span.h"
|
#include "mozilla/Span.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "base/basictypes.h"
|
#include "base/basictypes.h"
|
||||||
#include "base/process.h"
|
#include "base/process.h"
|
||||||
|
#include "chrome/common/ipc_message_utils.h"
|
||||||
|
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "base/shared_memory.h"
|
|
||||||
|
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/ipc/SharedMemory.h"
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
|
|
||||||
@@ -30,28 +28,29 @@ namespace mozilla {
|
|||||||
// compromised and then receives a frozen handle.
|
// compromised and then receives a frozen handle.
|
||||||
TEST(IPCSharedMemory, FreezeAndMapRW)
|
TEST(IPCSharedMemory, FreezeAndMapRW)
|
||||||
{
|
{
|
||||||
base::SharedMemory shm;
|
auto shm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
|
||||||
// Create and initialize
|
// Create and initialize
|
||||||
ASSERT_TRUE(shm.CreateFreezeable(1));
|
ASSERT_TRUE(shm->CreateFreezable(1));
|
||||||
ASSERT_TRUE(shm.Map(1));
|
ASSERT_TRUE(shm->Map(1));
|
||||||
auto mem = reinterpret_cast<char*>(shm.memory());
|
auto* mem = reinterpret_cast<char*>(shm->Memory());
|
||||||
ASSERT_TRUE(mem);
|
ASSERT_TRUE(mem);
|
||||||
*mem = 'A';
|
*mem = 'A';
|
||||||
|
|
||||||
// Freeze
|
// Freeze
|
||||||
ASSERT_TRUE(shm.Freeze());
|
ASSERT_TRUE(shm->Freeze());
|
||||||
ASSERT_FALSE(shm.memory());
|
ASSERT_FALSE(shm->Memory());
|
||||||
|
|
||||||
// Re-create as writeable
|
// Re-create as writeable
|
||||||
auto handle = shm.TakeHandle();
|
auto handle = shm->TakeHandleAndUnmap();
|
||||||
ASSERT_TRUE(shm.IsHandleValid(handle));
|
ASSERT_TRUE(shm->IsHandleValid(handle));
|
||||||
ASSERT_FALSE(shm.IsValid());
|
ASSERT_FALSE(shm->IsValid());
|
||||||
ASSERT_TRUE(shm.SetHandle(std::move(handle), /* read-only */ false));
|
ASSERT_TRUE(shm->SetHandle(std::move(handle),
|
||||||
ASSERT_TRUE(shm.IsValid());
|
ipc::SharedMemory::OpenRights::RightsReadWrite));
|
||||||
|
ASSERT_TRUE(shm->IsValid());
|
||||||
|
|
||||||
// This should fail
|
// This should fail
|
||||||
EXPECT_FALSE(shm.Map(1));
|
EXPECT_FALSE(shm->Map(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to restore write permissions to a frozen mapping. Threat
|
// Try to restore write permissions to a frozen mapping. Threat
|
||||||
@@ -60,22 +59,22 @@ TEST(IPCSharedMemory, FreezeAndMapRW)
|
|||||||
// proof-of-concept at https://crbug.com/project-zero/1671 ).
|
// proof-of-concept at https://crbug.com/project-zero/1671 ).
|
||||||
TEST(IPCSharedMemory, FreezeAndReprotect)
|
TEST(IPCSharedMemory, FreezeAndReprotect)
|
||||||
{
|
{
|
||||||
base::SharedMemory shm;
|
auto shm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
|
||||||
// Create and initialize
|
// Create and initialize
|
||||||
ASSERT_TRUE(shm.CreateFreezeable(1));
|
ASSERT_TRUE(shm->CreateFreezable(1));
|
||||||
ASSERT_TRUE(shm.Map(1));
|
ASSERT_TRUE(shm->Map(1));
|
||||||
auto mem = reinterpret_cast<char*>(shm.memory());
|
auto* mem = reinterpret_cast<char*>(shm->Memory());
|
||||||
ASSERT_TRUE(mem);
|
ASSERT_TRUE(mem);
|
||||||
*mem = 'A';
|
*mem = 'A';
|
||||||
|
|
||||||
// Freeze
|
// Freeze
|
||||||
ASSERT_TRUE(shm.Freeze());
|
ASSERT_TRUE(shm->Freeze());
|
||||||
ASSERT_FALSE(shm.memory());
|
ASSERT_FALSE(shm->Memory());
|
||||||
|
|
||||||
// Re-map
|
// Re-map
|
||||||
ASSERT_TRUE(shm.Map(1));
|
ASSERT_TRUE(shm->Map(1));
|
||||||
mem = reinterpret_cast<char*>(shm.memory());
|
mem = reinterpret_cast<char*>(shm->Memory());
|
||||||
ASSERT_EQ(*mem, 'A');
|
ASSERT_EQ(*mem, 'A');
|
||||||
|
|
||||||
// Try to alter protection; should fail
|
// Try to alter protection; should fail
|
||||||
@@ -83,32 +82,39 @@ TEST(IPCSharedMemory, FreezeAndReprotect)
|
|||||||
mem, 1, ipc::SharedMemory::RightsReadWrite));
|
mem, 1, ipc::SharedMemory::RightsReadWrite));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef XP_WIN
|
#if !defined(XP_WIN) && !defined(XP_DARWIN)
|
||||||
// This essentially tests whether FreezeAndReprotect would have failed
|
// This essentially tests whether FreezeAndReprotect would have failed
|
||||||
// without the freeze. It doesn't work on Windows: VirtualProtect
|
// without the freeze.
|
||||||
// can't exceed the permissions set in MapViewOfFile regardless of the
|
//
|
||||||
// security status of the original handle.
|
// It doesn't work on Windows: VirtualProtect can't exceed the permissions set
|
||||||
|
// in MapViewOfFile regardless of the security status of the original handle.
|
||||||
|
//
|
||||||
|
// It doesn't work on MacOS: we can set a higher max_protection for the memory
|
||||||
|
// when creating the handle, but we wouldn't want to do this for freezable
|
||||||
|
// handles (to prevent creating additional RW mappings that break the memory
|
||||||
|
// freezing invariants).
|
||||||
TEST(IPCSharedMemory, Reprotect)
|
TEST(IPCSharedMemory, Reprotect)
|
||||||
{
|
{
|
||||||
base::SharedMemory shm;
|
auto shm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
|
||||||
// Create and initialize
|
// Create and initialize
|
||||||
ASSERT_TRUE(shm.CreateFreezeable(1));
|
ASSERT_TRUE(shm->CreateFreezable(1));
|
||||||
ASSERT_TRUE(shm.Map(1));
|
ASSERT_TRUE(shm->Map(1));
|
||||||
auto mem = reinterpret_cast<char*>(shm.memory());
|
auto* mem = reinterpret_cast<char*>(shm->Memory());
|
||||||
ASSERT_TRUE(mem);
|
ASSERT_TRUE(mem);
|
||||||
*mem = 'A';
|
*mem = 'A';
|
||||||
|
|
||||||
// Re-create as read-only
|
// Re-create as read-only
|
||||||
auto handle = shm.TakeHandle();
|
auto handle = shm->TakeHandleAndUnmap();
|
||||||
ASSERT_TRUE(shm.IsHandleValid(handle));
|
ASSERT_TRUE(shm->IsHandleValid(handle));
|
||||||
ASSERT_FALSE(shm.IsValid());
|
ASSERT_FALSE(shm->IsValid());
|
||||||
ASSERT_TRUE(shm.SetHandle(std::move(handle), /* read-only */ true));
|
ASSERT_TRUE(shm->SetHandle(std::move(handle),
|
||||||
ASSERT_TRUE(shm.IsValid());
|
ipc::SharedMemory::OpenRights::RightsReadOnly));
|
||||||
|
ASSERT_TRUE(shm->IsValid());
|
||||||
|
|
||||||
// Re-map
|
// Re-map
|
||||||
ASSERT_TRUE(shm.Map(1));
|
ASSERT_TRUE(shm->Map(1));
|
||||||
mem = reinterpret_cast<char*>(shm.memory());
|
mem = reinterpret_cast<char*>(shm->Memory());
|
||||||
ASSERT_EQ(*mem, 'A');
|
ASSERT_EQ(*mem, 'A');
|
||||||
|
|
||||||
// Try to alter protection; should succeed, because not frozen
|
// Try to alter protection; should succeed, because not frozen
|
||||||
@@ -123,23 +129,23 @@ TEST(IPCSharedMemory, Reprotect)
|
|||||||
// See also https://crbug.com/338538
|
// See also https://crbug.com/338538
|
||||||
TEST(IPCSharedMemory, WinUnfreeze)
|
TEST(IPCSharedMemory, WinUnfreeze)
|
||||||
{
|
{
|
||||||
base::SharedMemory shm;
|
auto shm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
|
||||||
// Create and initialize
|
// Create and initialize
|
||||||
ASSERT_TRUE(shm.CreateFreezeable(1));
|
ASSERT_TRUE(shm->CreateFreezable(1));
|
||||||
ASSERT_TRUE(shm.Map(1));
|
ASSERT_TRUE(shm->Map(1));
|
||||||
auto mem = reinterpret_cast<char*>(shm.memory());
|
auto* mem = reinterpret_cast<char*>(shm->Memory());
|
||||||
ASSERT_TRUE(mem);
|
ASSERT_TRUE(mem);
|
||||||
*mem = 'A';
|
*mem = 'A';
|
||||||
|
|
||||||
// Freeze
|
// Freeze
|
||||||
ASSERT_TRUE(shm.Freeze());
|
ASSERT_TRUE(shm->Freeze());
|
||||||
ASSERT_FALSE(shm.memory());
|
ASSERT_FALSE(shm->Memory());
|
||||||
|
|
||||||
// Extract handle.
|
// Extract handle.
|
||||||
auto handle = shm.TakeHandle();
|
auto handle = shm->TakeHandleAndUnmap();
|
||||||
ASSERT_TRUE(shm.IsHandleValid(handle));
|
ASSERT_TRUE(shm->IsHandleValid(handle));
|
||||||
ASSERT_FALSE(shm.IsValid());
|
ASSERT_FALSE(shm->IsValid());
|
||||||
|
|
||||||
// Unfreeze.
|
// Unfreeze.
|
||||||
HANDLE newHandle = INVALID_HANDLE_VALUE;
|
HANDLE newHandle = INVALID_HANDLE_VALUE;
|
||||||
@@ -154,24 +160,25 @@ TEST(IPCSharedMemory, WinUnfreeze)
|
|||||||
// mapping in the case that the page wasn't accessed before the copy.
|
// mapping in the case that the page wasn't accessed before the copy.
|
||||||
TEST(IPCSharedMemory, ROCopyAndWrite)
|
TEST(IPCSharedMemory, ROCopyAndWrite)
|
||||||
{
|
{
|
||||||
base::SharedMemory shmRW, shmRO;
|
auto shmRW = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
auto shmRO = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
|
||||||
// Create and initialize
|
// Create and initialize
|
||||||
ASSERT_TRUE(shmRW.CreateFreezeable(1));
|
ASSERT_TRUE(shmRW->CreateFreezable(1));
|
||||||
ASSERT_TRUE(shmRW.Map(1));
|
ASSERT_TRUE(shmRW->Map(1));
|
||||||
auto memRW = reinterpret_cast<char*>(shmRW.memory());
|
auto* memRW = reinterpret_cast<char*>(shmRW->Memory());
|
||||||
ASSERT_TRUE(memRW);
|
ASSERT_TRUE(memRW);
|
||||||
|
|
||||||
// Create read-only copy
|
// Create read-only copy
|
||||||
ASSERT_TRUE(shmRW.ReadOnlyCopy(&shmRO));
|
ASSERT_TRUE(shmRW->ReadOnlyCopy(shmRO));
|
||||||
EXPECT_FALSE(shmRW.IsValid());
|
EXPECT_FALSE(shmRW->IsValid());
|
||||||
ASSERT_EQ(shmRW.memory(), memRW);
|
ASSERT_EQ(shmRW->Memory(), memRW);
|
||||||
ASSERT_EQ(shmRO.max_size(), size_t(1));
|
ASSERT_EQ(shmRO->MaxSize(), size_t(1));
|
||||||
|
|
||||||
// Map read-only
|
// Map read-only
|
||||||
ASSERT_TRUE(shmRO.IsValid());
|
ASSERT_TRUE(shmRO->IsValid());
|
||||||
ASSERT_TRUE(shmRO.Map(1));
|
ASSERT_TRUE(shmRO->Map(1));
|
||||||
auto memRO = reinterpret_cast<const char*>(shmRO.memory());
|
const auto* memRO = reinterpret_cast<const char*>(shmRO->Memory());
|
||||||
ASSERT_TRUE(memRO);
|
ASSERT_TRUE(memRO);
|
||||||
ASSERT_NE(memRW, memRO);
|
ASSERT_NE(memRW, memRO);
|
||||||
|
|
||||||
@@ -185,25 +192,26 @@ TEST(IPCSharedMemory, ROCopyAndWrite)
|
|||||||
// (and, before that, sees the state as of when the copy was made).
|
// (and, before that, sees the state as of when the copy was made).
|
||||||
TEST(IPCSharedMemory, ROCopyAndRewrite)
|
TEST(IPCSharedMemory, ROCopyAndRewrite)
|
||||||
{
|
{
|
||||||
base::SharedMemory shmRW, shmRO;
|
auto shmRW = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
auto shmRO = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
|
||||||
// Create and initialize
|
// Create and initialize
|
||||||
ASSERT_TRUE(shmRW.CreateFreezeable(1));
|
ASSERT_TRUE(shmRW->CreateFreezable(1));
|
||||||
ASSERT_TRUE(shmRW.Map(1));
|
ASSERT_TRUE(shmRW->Map(1));
|
||||||
auto memRW = reinterpret_cast<char*>(shmRW.memory());
|
auto* memRW = reinterpret_cast<char*>(shmRW->Memory());
|
||||||
ASSERT_TRUE(memRW);
|
ASSERT_TRUE(memRW);
|
||||||
*memRW = 'A';
|
*memRW = 'A';
|
||||||
|
|
||||||
// Create read-only copy
|
// Create read-only copy
|
||||||
ASSERT_TRUE(shmRW.ReadOnlyCopy(&shmRO));
|
ASSERT_TRUE(shmRW->ReadOnlyCopy(shmRO));
|
||||||
EXPECT_FALSE(shmRW.IsValid());
|
EXPECT_FALSE(shmRW->IsValid());
|
||||||
ASSERT_EQ(shmRW.memory(), memRW);
|
ASSERT_EQ(shmRW->Memory(), memRW);
|
||||||
ASSERT_EQ(shmRO.max_size(), size_t(1));
|
ASSERT_EQ(shmRO->MaxSize(), size_t(1));
|
||||||
|
|
||||||
// Map read-only
|
// Map read-only
|
||||||
ASSERT_TRUE(shmRO.IsValid());
|
ASSERT_TRUE(shmRO->IsValid());
|
||||||
ASSERT_TRUE(shmRO.Map(1));
|
ASSERT_TRUE(shmRO->Map(1));
|
||||||
auto memRO = reinterpret_cast<const char*>(shmRO.memory());
|
const auto* memRO = reinterpret_cast<const char*>(shmRO->Memory());
|
||||||
ASSERT_TRUE(memRO);
|
ASSERT_TRUE(memRO);
|
||||||
ASSERT_NE(memRW, memRO);
|
ASSERT_NE(memRW, memRO);
|
||||||
|
|
||||||
@@ -217,49 +225,52 @@ TEST(IPCSharedMemory, ROCopyAndRewrite)
|
|||||||
// See FreezeAndMapRW.
|
// See FreezeAndMapRW.
|
||||||
TEST(IPCSharedMemory, ROCopyAndMapRW)
|
TEST(IPCSharedMemory, ROCopyAndMapRW)
|
||||||
{
|
{
|
||||||
base::SharedMemory shmRW, shmRO;
|
auto shmRW = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
auto shmRO = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
|
||||||
// Create and initialize
|
// Create and initialize
|
||||||
ASSERT_TRUE(shmRW.CreateFreezeable(1));
|
ASSERT_TRUE(shmRW->CreateFreezable(1));
|
||||||
ASSERT_TRUE(shmRW.Map(1));
|
ASSERT_TRUE(shmRW->Map(1));
|
||||||
auto memRW = reinterpret_cast<char*>(shmRW.memory());
|
auto* memRW = reinterpret_cast<char*>(shmRW->Memory());
|
||||||
ASSERT_TRUE(memRW);
|
ASSERT_TRUE(memRW);
|
||||||
*memRW = 'A';
|
*memRW = 'A';
|
||||||
|
|
||||||
// Create read-only copy
|
// Create read-only copy
|
||||||
ASSERT_TRUE(shmRW.ReadOnlyCopy(&shmRO));
|
ASSERT_TRUE(shmRW->ReadOnlyCopy(shmRO));
|
||||||
ASSERT_TRUE(shmRO.IsValid());
|
ASSERT_TRUE(shmRO->IsValid());
|
||||||
|
|
||||||
// Re-create as writeable
|
// Re-create as writeable
|
||||||
auto handle = shmRO.TakeHandle();
|
auto handle = shmRO->TakeHandleAndUnmap();
|
||||||
ASSERT_TRUE(shmRO.IsHandleValid(handle));
|
ASSERT_TRUE(shmRO->IsHandleValid(handle));
|
||||||
ASSERT_FALSE(shmRO.IsValid());
|
ASSERT_FALSE(shmRO->IsValid());
|
||||||
ASSERT_TRUE(shmRO.SetHandle(std::move(handle), /* read-only */ false));
|
ASSERT_TRUE(shmRO->SetHandle(std::move(handle),
|
||||||
ASSERT_TRUE(shmRO.IsValid());
|
ipc::SharedMemory::OpenRights::RightsReadWrite));
|
||||||
|
ASSERT_TRUE(shmRO->IsValid());
|
||||||
|
|
||||||
// This should fail
|
// This should fail
|
||||||
EXPECT_FALSE(shmRO.Map(1));
|
EXPECT_FALSE(shmRO->Map(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// See FreezeAndReprotect
|
// See FreezeAndReprotect
|
||||||
TEST(IPCSharedMemory, ROCopyAndReprotect)
|
TEST(IPCSharedMemory, ROCopyAndReprotect)
|
||||||
{
|
{
|
||||||
base::SharedMemory shmRW, shmRO;
|
auto shmRW = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
auto shmRO = MakeRefPtr<ipc::SharedMemory>();
|
||||||
|
|
||||||
// Create and initialize
|
// Create and initialize
|
||||||
ASSERT_TRUE(shmRW.CreateFreezeable(1));
|
ASSERT_TRUE(shmRW->CreateFreezable(1));
|
||||||
ASSERT_TRUE(shmRW.Map(1));
|
ASSERT_TRUE(shmRW->Map(1));
|
||||||
auto memRW = reinterpret_cast<char*>(shmRW.memory());
|
auto* memRW = reinterpret_cast<char*>(shmRW->Memory());
|
||||||
ASSERT_TRUE(memRW);
|
ASSERT_TRUE(memRW);
|
||||||
*memRW = 'A';
|
*memRW = 'A';
|
||||||
|
|
||||||
// Create read-only copy
|
// Create read-only copy
|
||||||
ASSERT_TRUE(shmRW.ReadOnlyCopy(&shmRO));
|
ASSERT_TRUE(shmRW->ReadOnlyCopy(shmRO));
|
||||||
ASSERT_TRUE(shmRO.IsValid());
|
ASSERT_TRUE(shmRO->IsValid());
|
||||||
|
|
||||||
// Re-map
|
// Re-map
|
||||||
ASSERT_TRUE(shmRO.Map(1));
|
ASSERT_TRUE(shmRO->Map(1));
|
||||||
auto memRO = reinterpret_cast<char*>(shmRO.memory());
|
auto* memRO = reinterpret_cast<char*>(shmRO->Memory());
|
||||||
ASSERT_EQ(*memRO, 'A');
|
ASSERT_EQ(*memRO, 'A');
|
||||||
|
|
||||||
// Try to alter protection; should fail
|
// Try to alter protection; should fail
|
||||||
@@ -267,20 +278,6 @@ TEST(IPCSharedMemory, ROCopyAndReprotect)
|
|||||||
memRO, 1, ipc::SharedMemory::RightsReadWrite));
|
memRO, 1, ipc::SharedMemory::RightsReadWrite));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(IPCSharedMemory, IsZero)
|
|
||||||
{
|
|
||||||
base::SharedMemory shm;
|
|
||||||
|
|
||||||
static constexpr size_t kSize = 65536;
|
|
||||||
ASSERT_TRUE(shm.Create(kSize));
|
|
||||||
ASSERT_TRUE(shm.Map(kSize));
|
|
||||||
|
|
||||||
auto* mem = reinterpret_cast<char*>(shm.memory());
|
|
||||||
for (size_t i = 0; i < kSize; ++i) {
|
|
||||||
ASSERT_EQ(mem[i], 0) << "offset " << i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef FUZZING
|
#ifndef FUZZING
|
||||||
TEST(IPCSharedMemory, BasicIsZero)
|
TEST(IPCSharedMemory, BasicIsZero)
|
||||||
{
|
{
|
||||||
@@ -314,9 +311,10 @@ TEST(IPCSharedMemory, IsMemfd)
|
|||||||
ASSERT_EQ(sscanf(uts.release, "%d.%d", &major, &minor), 2);
|
ASSERT_EQ(sscanf(uts.release, "%d.%d", &major, &minor), 2);
|
||||||
bool expectMemfd = major > kMajor || (major == kMajor && minor >= kMinor);
|
bool expectMemfd = major > kMajor || (major == kMajor && minor >= kMinor);
|
||||||
|
|
||||||
base::SharedMemory shm;
|
auto shm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
ASSERT_TRUE(shm.Create(1));
|
|
||||||
UniqueFileHandle fd = shm.TakeHandle();
|
ASSERT_TRUE(shm->Create(1));
|
||||||
|
UniqueFileHandle fd = shm->TakeHandleAndUnmap();
|
||||||
ASSERT_TRUE(fd);
|
ASSERT_TRUE(fd);
|
||||||
|
|
||||||
struct statfs fs;
|
struct statfs fs;
|
||||||
|
|||||||
@@ -92,50 +92,8 @@ Result<Ok, nsresult> AutoMemMap::initInternal(PRFileMapProtect prot,
|
|||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XP_WIN
|
|
||||||
|
|
||||||
Result<Ok, nsresult> AutoMemMap::initWithHandle(const FileDescriptor& file,
|
|
||||||
size_t size,
|
|
||||||
PRFileMapProtect prot) {
|
|
||||||
MOZ_ASSERT(!fd);
|
|
||||||
MOZ_ASSERT(!handle_);
|
|
||||||
if (!file.IsValid()) {
|
|
||||||
return Err(NS_ERROR_INVALID_ARG);
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_ = file.ClonePlatformHandle().release();
|
|
||||||
|
|
||||||
MOZ_ASSERT(!addr);
|
|
||||||
|
|
||||||
size_ = size;
|
|
||||||
|
|
||||||
addr = MapViewOfFile(
|
|
||||||
handle_, prot == PR_PROT_READONLY ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS,
|
|
||||||
0, 0, size);
|
|
||||||
if (!addr) {
|
|
||||||
return Err(NS_ERROR_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
FileDescriptor AutoMemMap::cloneHandle() const {
|
|
||||||
return FileDescriptor(handle_);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
Result<Ok, nsresult> AutoMemMap::initWithHandle(const FileDescriptor& file,
|
|
||||||
size_t size,
|
|
||||||
PRFileMapProtect prot) {
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(size > 0);
|
|
||||||
return init(file, prot, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileDescriptor AutoMemMap::cloneHandle() const { return cloneFileDescriptor(); }
|
FileDescriptor AutoMemMap::cloneHandle() const { return cloneFileDescriptor(); }
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void AutoMemMap::reset() {
|
void AutoMemMap::reset() {
|
||||||
if (addr && !persistent_) {
|
if (addr && !persistent_) {
|
||||||
Unused << NS_WARN_IF(PR_MemUnmap(addr, size()) != PR_SUCCESS);
|
Unused << NS_WARN_IF(PR_MemUnmap(addr, size()) != PR_SUCCESS);
|
||||||
@@ -145,12 +103,6 @@ void AutoMemMap::reset() {
|
|||||||
Unused << NS_WARN_IF(PR_CloseFileMap(fileMap) != PR_SUCCESS);
|
Unused << NS_WARN_IF(PR_CloseFileMap(fileMap) != PR_SUCCESS);
|
||||||
fileMap = nullptr;
|
fileMap = nullptr;
|
||||||
}
|
}
|
||||||
#ifdef XP_WIN
|
|
||||||
if (handle_) {
|
|
||||||
CloseHandle(handle_);
|
|
||||||
handle_ = nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
fd = nullptr;
|
fd = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,13 +37,6 @@ class AutoMemMap {
|
|||||||
PRFileMapProtect prot = PR_PROT_READONLY,
|
PRFileMapProtect prot = PR_PROT_READONLY,
|
||||||
size_t maybeSize = 0);
|
size_t maybeSize = 0);
|
||||||
|
|
||||||
// Initializes the mapped memory with a shared memory handle. On
|
|
||||||
// Unix-like systems, this is identical to the above init() method. On
|
|
||||||
// Windows, the FileDescriptor must be a handle for a file mapping,
|
|
||||||
// rather than a file descriptor.
|
|
||||||
Result<Ok, nsresult> initWithHandle(const FileDescriptor& file, size_t size,
|
|
||||||
PRFileMapProtect prot = PR_PROT_READONLY);
|
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
bool initialized() const { return addr; }
|
bool initialized() const { return addr; }
|
||||||
@@ -78,13 +71,6 @@ class AutoMemMap {
|
|||||||
AutoFDClose fd;
|
AutoFDClose fd;
|
||||||
PRFileMap* fileMap = nullptr;
|
PRFileMap* fileMap = nullptr;
|
||||||
|
|
||||||
#ifdef XP_WIN
|
|
||||||
// We can't include windows.h in this header, since it gets included
|
|
||||||
// by some binding headers (which are explicitly incompatible with
|
|
||||||
// windows.h). So we can't use the HANDLE type here.
|
|
||||||
void* handle_ = nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t size_ = 0;
|
uint32_t size_ = 0;
|
||||||
void* addr = nullptr;
|
void* addr = nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ void xpc::SelfHostedShmem::InitFromParent(ContentType aXdr) {
|
|||||||
MOZ_ASSERT(!mLen, "Shouldn't call this more than once");
|
MOZ_ASSERT(!mLen, "Shouldn't call this more than once");
|
||||||
|
|
||||||
size_t len = aXdr.Length();
|
size_t len = aXdr.Length();
|
||||||
auto shm = mozilla::MakeUnique<base::SharedMemory>();
|
auto shm = mozilla::MakeRefPtr<mozilla::ipc::SharedMemory>();
|
||||||
if (NS_WARN_IF(!shm->CreateFreezeable(len))) {
|
if (NS_WARN_IF(!shm->CreateFreezable(len))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,27 +52,29 @@ void xpc::SelfHostedShmem::InitFromParent(ContentType aXdr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* address = shm->memory();
|
void* address = shm->Memory();
|
||||||
memcpy(address, aXdr.Elements(), aXdr.LengthBytes());
|
memcpy(address, aXdr.Elements(), aXdr.LengthBytes());
|
||||||
|
|
||||||
base::SharedMemory roCopy;
|
RefPtr<mozilla::ipc::SharedMemory> roCopy =
|
||||||
if (NS_WARN_IF(!shm->ReadOnlyCopy(&roCopy))) {
|
mozilla::MakeRefPtr<mozilla::ipc::SharedMemory>();
|
||||||
|
if (NS_WARN_IF(!shm->ReadOnlyCopy(&*roCopy))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mMem = std::move(shm);
|
mMem = std::move(shm);
|
||||||
mHandle = roCopy.TakeHandle();
|
mHandle = roCopy->TakeHandleAndUnmap();
|
||||||
mLen = len;
|
mLen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool xpc::SelfHostedShmem::InitFromChild(::base::SharedMemoryHandle aHandle,
|
bool xpc::SelfHostedShmem::InitFromChild(
|
||||||
size_t aLen) {
|
mozilla::ipc::SharedMemoryHandle aHandle, size_t aLen) {
|
||||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(!mLen, "Shouldn't call this more than once");
|
MOZ_ASSERT(!mLen, "Shouldn't call this more than once");
|
||||||
|
|
||||||
auto shm = mozilla::MakeUnique<base::SharedMemory>();
|
auto shm = mozilla::MakeRefPtr<mozilla::ipc::SharedMemory>();
|
||||||
if (NS_WARN_IF(!shm->SetHandle(std::move(aHandle), /* read_only */ true))) {
|
if (NS_WARN_IF(!shm->SetHandle(std::move(aHandle),
|
||||||
|
mozilla::ipc::SharedMemory::RightsReadOnly))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,10 +94,10 @@ xpc::SelfHostedShmem::ContentType xpc::SelfHostedShmem::Content() const {
|
|||||||
MOZ_ASSERT(mLen == 0);
|
MOZ_ASSERT(mLen == 0);
|
||||||
return ContentType();
|
return ContentType();
|
||||||
}
|
}
|
||||||
return ContentType(reinterpret_cast<uint8_t*>(mMem->memory()), mLen);
|
return ContentType(reinterpret_cast<uint8_t*>(mMem->Memory()), mLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mozilla::UniqueFileHandle& xpc::SelfHostedShmem::Handle() const {
|
const mozilla::ipc::SharedMemoryHandle& xpc::SelfHostedShmem::Handle() const {
|
||||||
return mHandle;
|
return mHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,12 @@
|
|||||||
#ifndef xpcselfhostedshmem_h___
|
#ifndef xpcselfhostedshmem_h___
|
||||||
#define xpcselfhostedshmem_h___
|
#define xpcselfhostedshmem_h___
|
||||||
|
|
||||||
#include "base/shared_memory.h"
|
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
#include "mozilla/UniquePtrExtensions.h"
|
#include "mozilla/UniquePtrExtensions.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/Span.h"
|
#include "mozilla/Span.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "nsIMemoryReporter.h"
|
#include "nsIMemoryReporter.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "nsIThread.h"
|
#include "nsIThread.h"
|
||||||
@@ -47,14 +48,14 @@ class SelfHostedShmem final : public nsIMemoryReporter {
|
|||||||
//
|
//
|
||||||
// This function is not thread-safe and should be call at most once and from
|
// This function is not thread-safe and should be call at most once and from
|
||||||
// the main thread.
|
// the main thread.
|
||||||
[[nodiscard]] bool InitFromChild(base::SharedMemoryHandle aHandle,
|
[[nodiscard]] bool InitFromChild(mozilla::ipc::SharedMemoryHandle aHandle,
|
||||||
size_t aLen);
|
size_t aLen);
|
||||||
|
|
||||||
// Return a span over the read-only XDR content of the self-hosted stencil.
|
// Return a span over the read-only XDR content of the self-hosted stencil.
|
||||||
ContentType Content() const;
|
ContentType Content() const;
|
||||||
|
|
||||||
// Return the file handle which is under which the content is mapped.
|
// Return the file handle which is under which the content is mapped.
|
||||||
const mozilla::UniqueFileHandle& Handle() const;
|
const mozilla::ipc::SharedMemoryHandle& Handle() const;
|
||||||
|
|
||||||
// Register this class to the memory reporter service.
|
// Register this class to the memory reporter service.
|
||||||
void InitMemoryReporter();
|
void InitMemoryReporter();
|
||||||
@@ -75,10 +76,10 @@ class SelfHostedShmem final : public nsIMemoryReporter {
|
|||||||
|
|
||||||
// read-only file Handle used to transfer from the parent process to content
|
// read-only file Handle used to transfer from the parent process to content
|
||||||
// processes.
|
// processes.
|
||||||
mozilla::UniqueFileHandle mHandle;
|
mozilla::ipc::SharedMemoryHandle mHandle;
|
||||||
|
|
||||||
// Shared memory used by JS runtime initialization.
|
// Shared memory used by JS runtime initialization.
|
||||||
mozilla::UniquePtr<base::SharedMemory> mMem;
|
RefPtr<mozilla::ipc::SharedMemory> mMem;
|
||||||
|
|
||||||
// Length of the content within the shared memory.
|
// Length of the content within the shared memory.
|
||||||
size_t mLen = 0;
|
size_t mLen = 0;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "nsAppDirectoryServiceDefs.h"
|
#include "nsAppDirectoryServiceDefs.h"
|
||||||
#include "nsExceptionHandler.h"
|
#include "nsExceptionHandler.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
|
#include "mozilla/NeverDestroyed.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/StaticPrefs_layout.h"
|
#include "mozilla/StaticPrefs_layout.h"
|
||||||
#include "mozilla/StyleSheet.h"
|
#include "mozilla/StyleSheet.h"
|
||||||
@@ -104,6 +105,11 @@ namespace mozilla {
|
|||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace css;
|
using namespace css;
|
||||||
|
|
||||||
|
mozilla::ipc::SharedMemoryHandle& sSharedMemoryHandle() {
|
||||||
|
static NeverDestroyed<mozilla::ipc::SharedMemoryHandle> handle;
|
||||||
|
return *handle;
|
||||||
|
}
|
||||||
|
|
||||||
#define PREF_LEGACY_STYLESHEET_CUSTOMIZATION \
|
#define PREF_LEGACY_STYLESHEET_CUSTOMIZATION \
|
||||||
"toolkit.legacyUserProfileCustomizations.stylesheets"
|
"toolkit.legacyUserProfileCustomizations.stylesheets"
|
||||||
|
|
||||||
@@ -173,7 +179,7 @@ GlobalStyleSheetCache::CollectReports(nsIHandleReportCallback* aHandleReport,
|
|||||||
if (XRE_IsParentProcess()) {
|
if (XRE_IsParentProcess()) {
|
||||||
MOZ_COLLECT_REPORT(
|
MOZ_COLLECT_REPORT(
|
||||||
"explicit/layout/style-sheet-cache/shared", KIND_NONHEAP, UNITS_BYTES,
|
"explicit/layout/style-sheet-cache/shared", KIND_NONHEAP, UNITS_BYTES,
|
||||||
sSharedMemory ? sUsedSharedMemory : 0,
|
sSharedMemory.IsEmpty() ? 0 : sUsedSharedMemory,
|
||||||
"Memory used for built-in style sheets that are shared to "
|
"Memory used for built-in style sheets that are shared to "
|
||||||
"child processes.");
|
"child processes.");
|
||||||
}
|
}
|
||||||
@@ -236,10 +242,10 @@ GlobalStyleSheetCache::GlobalStyleSheetCache() {
|
|||||||
if (XRE_IsParentProcess()) {
|
if (XRE_IsParentProcess()) {
|
||||||
// Load the style sheets and store them in a new shared memory buffer.
|
// Load the style sheets and store them in a new shared memory buffer.
|
||||||
InitSharedSheetsInParent();
|
InitSharedSheetsInParent();
|
||||||
} else if (sSharedMemory) {
|
} else if (!sSharedMemory.IsEmpty()) {
|
||||||
// Use the shared memory handle that was given to us by a SetSharedMemory
|
// Use the shared memory that was given to us by a SetSharedMemory call
|
||||||
// call under ContentChild::InitXPCOM.
|
// under ContentChild::InitXPCOM.
|
||||||
MOZ_ASSERT(sSharedMemory->memory(),
|
MOZ_ASSERT(sSharedMemory.data(),
|
||||||
"GlobalStyleSheetCache::SetSharedMemory should have mapped "
|
"GlobalStyleSheetCache::SetSharedMemory should have mapped "
|
||||||
"the shared memory");
|
"the shared memory");
|
||||||
}
|
}
|
||||||
@@ -258,8 +264,8 @@ GlobalStyleSheetCache::GlobalStyleSheetCache() {
|
|||||||
// In the parent process, this means we'll just leave our eagerly loaded
|
// In the parent process, this means we'll just leave our eagerly loaded
|
||||||
// non-shared sheets in the mFooSheet fields. In a content process, we'll
|
// non-shared sheets in the mFooSheet fields. In a content process, we'll
|
||||||
// lazily load our own copies of the sheets later.
|
// lazily load our own copies of the sheets later.
|
||||||
if (sSharedMemory) {
|
if (!sSharedMemory.IsEmpty()) {
|
||||||
if (auto* header = static_cast<Header*>(sSharedMemory->memory())) {
|
if (auto* header = reinterpret_cast<Header*>(sSharedMemory.data())) {
|
||||||
MOZ_RELEASE_ASSERT(header->mMagic == Header::kMagic);
|
MOZ_RELEASE_ASSERT(header->mMagic == Header::kMagic);
|
||||||
|
|
||||||
#define STYLE_SHEET(identifier_, url_, shared_) \
|
#define STYLE_SHEET(identifier_, url_, shared_) \
|
||||||
@@ -299,10 +305,10 @@ void GlobalStyleSheetCache::LoadSheetFromSharedMemory(
|
|||||||
|
|
||||||
void GlobalStyleSheetCache::InitSharedSheetsInParent() {
|
void GlobalStyleSheetCache::InitSharedSheetsInParent() {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
MOZ_RELEASE_ASSERT(!sSharedMemory);
|
MOZ_RELEASE_ASSERT(sSharedMemory.IsEmpty());
|
||||||
|
|
||||||
auto shm = MakeUnique<base::SharedMemory>();
|
auto shm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (NS_WARN_IF(!shm->CreateFreezeable(kSharedMemorySize))) {
|
if (NS_WARN_IF(!shm->CreateFreezable(kSharedMemorySize))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,7 +340,7 @@ void GlobalStyleSheetCache::InitSharedSheetsInParent() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void* address = nullptr;
|
void* address = nullptr;
|
||||||
if (void* p = base::SharedMemory::FindFreeAddressSpace(2 * kOffset)) {
|
if (void* p = ipc::SharedMemory::FindFreeAddressSpace(2 * kOffset)) {
|
||||||
address = reinterpret_cast<void*>(uintptr_t(p) + kOffset);
|
address = reinterpret_cast<void*>(uintptr_t(p) + kOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,7 +352,7 @@ void GlobalStyleSheetCache::InitSharedSheetsInParent() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
address = shm->memory();
|
address = shm->Memory();
|
||||||
|
|
||||||
auto* header = static_cast<Header*>(address);
|
auto* header = static_cast<Header*>(address);
|
||||||
header->mMagic = Header::kMagic;
|
header->mMagic = Header::kMagic;
|
||||||
@@ -405,7 +411,8 @@ void GlobalStyleSheetCache::InitSharedSheetsInParent() {
|
|||||||
(Servo_SharedMemoryBuilder_GetLength(builder.get()) + pageSize - 1) &
|
(Servo_SharedMemoryBuilder_GetLength(builder.get()) + pageSize - 1) &
|
||||||
~(pageSize - 1);
|
~(pageSize - 1);
|
||||||
|
|
||||||
sSharedMemory = shm.release();
|
sSharedMemory = shm->TakeMapping();
|
||||||
|
sSharedMemoryHandle() = shm->TakeHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalStyleSheetCache::~GlobalStyleSheetCache() {
|
GlobalStyleSheetCache::~GlobalStyleSheetCache() {
|
||||||
@@ -528,25 +535,26 @@ RefPtr<StyleSheet> GlobalStyleSheetCache::LoadSheet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void GlobalStyleSheetCache::SetSharedMemory(
|
/* static */ void GlobalStyleSheetCache::SetSharedMemory(
|
||||||
base::SharedMemoryHandle aHandle, uintptr_t aAddress) {
|
ipc::SharedMemory::Handle aHandle, uintptr_t aAddress) {
|
||||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||||
MOZ_ASSERT(!gStyleCache, "Too late, GlobalStyleSheetCache already created!");
|
MOZ_ASSERT(!gStyleCache, "Too late, GlobalStyleSheetCache already created!");
|
||||||
MOZ_ASSERT(!sSharedMemory, "Shouldn't call this more than once");
|
MOZ_ASSERT(sSharedMemory.IsEmpty(), "Shouldn't call this more than once");
|
||||||
|
|
||||||
auto shm = MakeUnique<base::SharedMemory>();
|
auto shm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (!shm->SetHandle(std::move(aHandle), /* read_only */ true)) {
|
if (!shm->SetHandle(std::move(aHandle), ipc::SharedMemory::RightsReadOnly)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shm->Map(kSharedMemorySize, reinterpret_cast<void*>(aAddress))) {
|
if (shm->Map(kSharedMemorySize, reinterpret_cast<void*>(aAddress))) {
|
||||||
sSharedMemory = shm.release();
|
sSharedMemory = shm->TakeMapping();
|
||||||
|
sSharedMemoryHandle() = shm->TakeHandle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base::SharedMemoryHandle GlobalStyleSheetCache::CloneHandle() {
|
ipc::SharedMemoryHandle GlobalStyleSheetCache::CloneHandle() {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
if (sSharedMemory) {
|
if (ipc::SharedMemory::IsHandleValid(sSharedMemoryHandle())) {
|
||||||
return sSharedMemory->CloneHandle();
|
return ipc::SharedMemory::CloneHandle(sSharedMemoryHandle());
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -555,7 +563,7 @@ StaticRefPtr<GlobalStyleSheetCache> GlobalStyleSheetCache::gStyleCache;
|
|||||||
StaticRefPtr<css::Loader> GlobalStyleSheetCache::gCSSLoader;
|
StaticRefPtr<css::Loader> GlobalStyleSheetCache::gCSSLoader;
|
||||||
StaticRefPtr<nsIURI> GlobalStyleSheetCache::gUserContentSheetURL;
|
StaticRefPtr<nsIURI> GlobalStyleSheetCache::gUserContentSheetURL;
|
||||||
|
|
||||||
StaticAutoPtr<base::SharedMemory> GlobalStyleSheetCache::sSharedMemory;
|
Span<uint8_t> GlobalStyleSheetCache::sSharedMemory;
|
||||||
size_t GlobalStyleSheetCache::sUsedSharedMemory;
|
size_t GlobalStyleSheetCache::sUsedSharedMemory;
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include "nsIMemoryReporter.h"
|
#include "nsIMemoryReporter.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "base/shared_memory.h"
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/PreferenceSheet.h"
|
#include "mozilla/PreferenceSheet.h"
|
||||||
@@ -17,6 +16,7 @@
|
|||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
#include "mozilla/UserAgentStyleSheetID.h"
|
#include "mozilla/UserAgentStyleSheetID.h"
|
||||||
#include "mozilla/css/Loader.h"
|
#include "mozilla/css/Loader.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
|
|
||||||
class nsIFile;
|
class nsIFile;
|
||||||
class nsIURI;
|
class nsIURI;
|
||||||
@@ -60,18 +60,18 @@ class GlobalStyleSheetCache final : public nsIObserver,
|
|||||||
// Called early on in a content process' life from
|
// Called early on in a content process' life from
|
||||||
// ContentChild::InitSharedUASheets, before the GlobalStyleSheetCache
|
// ContentChild::InitSharedUASheets, before the GlobalStyleSheetCache
|
||||||
// singleton has been created.
|
// singleton has been created.
|
||||||
static void SetSharedMemory(base::SharedMemoryHandle aHandle,
|
static void SetSharedMemory(mozilla::ipc::SharedMemory::Handle aHandle,
|
||||||
uintptr_t aAddress);
|
uintptr_t aAddress);
|
||||||
|
|
||||||
// Obtain a shared memory handle for the shared UA sheets to pass into a
|
// Obtain a shared memory handle for the shared UA sheets to pass into a
|
||||||
// content process. Called by ContentParent::InitInternal shortly after
|
// content process. Called by ContentParent::InitInternal shortly after
|
||||||
// a content process has been created.
|
// a content process has been created.
|
||||||
base::SharedMemoryHandle CloneHandle();
|
mozilla::ipc::SharedMemoryHandle CloneHandle();
|
||||||
|
|
||||||
// Returns the address of the shared memory segment that holds the shared UA
|
// Returns the address of the shared memory segment that holds the shared UA
|
||||||
// sheets.
|
// sheets.
|
||||||
uintptr_t GetSharedMemoryAddress() {
|
uintptr_t GetSharedMemoryAddress() {
|
||||||
return sSharedMemory ? uintptr_t(sSharedMemory->memory()) : 0;
|
return sSharedMemory.IsEmpty() ? 0 : uintptr_t(sSharedMemory.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size of the shared memory buffer we'll create to store the shared UA
|
// Size of the shared memory buffer we'll create to store the shared UA
|
||||||
@@ -120,7 +120,7 @@ class GlobalStyleSheetCache final : public nsIObserver,
|
|||||||
RefPtr<StyleSheet> mUserContentSheet;
|
RefPtr<StyleSheet> mUserContentSheet;
|
||||||
|
|
||||||
// Shared memory segment storing shared style sheets.
|
// Shared memory segment storing shared style sheets.
|
||||||
static StaticAutoPtr<base::SharedMemory> sSharedMemory;
|
static Span<uint8_t> sSharedMemory;
|
||||||
|
|
||||||
// How much of the shared memory buffer we ended up using. Used for memory
|
// How much of the shared memory buffer we ended up using. Used for memory
|
||||||
// reporting in the parent process.
|
// reporting in the parent process.
|
||||||
|
|||||||
@@ -3833,7 +3833,7 @@ void Preferences::DeserializePreferences(char* aStr, size_t aPrefsLen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
FileDescriptor Preferences::EnsureSnapshot(size_t* aSize) {
|
mozilla::ipc::SharedMemoryHandle Preferences::EnsureSnapshot(size_t* aSize) {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
@@ -3883,11 +3883,12 @@ FileDescriptor Preferences::EnsureSnapshot(size_t* aSize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*aSize = gSharedMap->MapSize();
|
*aSize = gSharedMap->MapSize();
|
||||||
return gSharedMap->CloneFileDescriptor();
|
return gSharedMap->CloneHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
void Preferences::InitSnapshot(const FileDescriptor& aHandle, size_t aSize) {
|
void Preferences::InitSnapshot(const mozilla::ipc::SharedMemoryHandle& aHandle,
|
||||||
|
size_t aSize) {
|
||||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||||
MOZ_ASSERT(!gSharedMap);
|
MOZ_ASSERT(!gSharedMap);
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/MozPromise.h"
|
#include "mozilla/MozPromise.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "nsIPrefBranch.h"
|
#include "nsIPrefBranch.h"
|
||||||
@@ -409,8 +410,11 @@ class Preferences final : public nsIPrefService,
|
|||||||
bool aIsDestinationWebContentProcess);
|
bool aIsDestinationWebContentProcess);
|
||||||
static void DeserializePreferences(char* aStr, size_t aPrefsLen);
|
static void DeserializePreferences(char* aStr, size_t aPrefsLen);
|
||||||
|
|
||||||
static mozilla::ipc::FileDescriptor EnsureSnapshot(size_t* aSize);
|
#ifndef RUST_BINDGEN
|
||||||
static void InitSnapshot(const mozilla::ipc::FileDescriptor&, size_t aSize);
|
static mozilla::ipc::SharedMemoryHandle EnsureSnapshot(size_t* aSize);
|
||||||
|
static void InitSnapshot(const mozilla::ipc::SharedMemoryHandle&,
|
||||||
|
size_t aSize);
|
||||||
|
#endif
|
||||||
|
|
||||||
// When a single pref is changed in the parent process, these methods are
|
// When a single pref is changed in the parent process, these methods are
|
||||||
// used to pass the update to content processes.
|
// used to pass the update to content processes.
|
||||||
|
|||||||
@@ -13,8 +13,6 @@
|
|||||||
#include "mozilla/Try.h"
|
#include "mozilla/Try.h"
|
||||||
#include "mozilla/ipc/FileDescriptor.h"
|
#include "mozilla/ipc/FileDescriptor.h"
|
||||||
|
|
||||||
using namespace mozilla::loader;
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
using namespace ipc;
|
using namespace ipc;
|
||||||
@@ -24,24 +22,38 @@ static inline size_t GetAlignmentOffset(size_t aOffset, size_t aAlign) {
|
|||||||
return mod ? aAlign - mod : 0;
|
return mod ? aAlign - mod : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPrefMap::SharedPrefMap(const FileDescriptor& aMapFile, size_t aMapSize) {
|
SharedPrefMap::SharedPrefMap(const SharedMemoryHandle& aMapHandle,
|
||||||
auto result = mMap.initWithHandle(aMapFile, aMapSize);
|
size_t aMapSize) {
|
||||||
MOZ_RELEASE_ASSERT(result.isOk());
|
auto map = MakeRefPtr<SharedMemory>();
|
||||||
|
{
|
||||||
|
auto result = map->SetHandle(SharedMemory::CloneHandle(aMapHandle),
|
||||||
|
SharedMemory::OpenRights::RightsReadOnly);
|
||||||
|
MOZ_RELEASE_ASSERT(result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto result = map->Map(aMapSize);
|
||||||
|
MOZ_RELEASE_ASSERT(result);
|
||||||
|
}
|
||||||
|
|
||||||
// We return literal nsCStrings pointing to the mapped data for preference
|
// We return literal nsCStrings pointing to the mapped data for preference
|
||||||
// names and string values, which means that we may still have references to
|
// names and string values, which means that we may still have references to
|
||||||
// the mapped data even after this instance is destroyed. That means that we
|
// the mapped data even after this instance is destroyed. That means that we
|
||||||
// need to keep the mapping alive until process shutdown, in order to be safe.
|
// need to keep the mapping alive until process shutdown, in order to be safe.
|
||||||
mMap.setPersistent();
|
mMappedMemory = map->TakeMapping();
|
||||||
|
mHandle = map->TakeHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPrefMap::SharedPrefMap(SharedPrefMapBuilder&& aBuilder) {
|
SharedPrefMap::SharedPrefMap(SharedPrefMapBuilder&& aBuilder) {
|
||||||
auto result = aBuilder.Finalize(mMap);
|
RefPtr<SharedMemory> map;
|
||||||
MOZ_RELEASE_ASSERT(result.isOk());
|
auto result = aBuilder.Finalize(map);
|
||||||
mMap.setPersistent();
|
MOZ_RELEASE_ASSERT(result.isOk() && map);
|
||||||
|
|
||||||
|
mMappedMemory = map->TakeMapping();
|
||||||
|
mHandle = map->TakeHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::ipc::FileDescriptor SharedPrefMap::CloneFileDescriptor() const {
|
mozilla::ipc::SharedMemoryHandle SharedPrefMap::CloneHandle() const {
|
||||||
return mMap.cloneHandle();
|
return SharedMemory::CloneHandle(mHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SharedPrefMap::Has(const char* aKey) const {
|
bool SharedPrefMap::Has(const char* aKey) const {
|
||||||
@@ -136,7 +148,8 @@ void SharedPrefMapBuilder::Add(const nsCString& aKey, const Flags& aFlags,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Ok, nsresult> SharedPrefMapBuilder::Finalize(loader::AutoMemMap& aMap) {
|
Result<Ok, nsresult> SharedPrefMapBuilder::Finalize(
|
||||||
|
RefPtr<SharedMemory>& aMap) {
|
||||||
using Header = SharedPrefMap::Header;
|
using Header = SharedPrefMap::Header;
|
||||||
|
|
||||||
// Create an array of entry pointers for the entry array, and sort it by
|
// Create an array of entry pointers for the entry array, and sort it by
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
#ifndef dom_ipc_SharedPrefMap_h
|
#ifndef dom_ipc_SharedPrefMap_h
|
||||||
#define dom_ipc_SharedPrefMap_h
|
#define dom_ipc_SharedPrefMap_h
|
||||||
|
|
||||||
#include "mozilla/AutoMemMap.h"
|
|
||||||
#include "mozilla/HashFunctions.h"
|
#include "mozilla/HashFunctions.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/Result.h"
|
#include "mozilla/Result.h"
|
||||||
#include "mozilla/dom/ipc/StringTable.h"
|
#include "mozilla/dom/ipc/StringTable.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "nsTHashMap.h"
|
#include "nsTHashMap.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@@ -52,8 +52,6 @@ class SharedPrefMapBuilder;
|
|||||||
// instance has been initialized, the memory that it allocates can never be
|
// instance has been initialized, the memory that it allocates can never be
|
||||||
// freed before process shutdown. Do not use it for short-lived mappings.
|
// freed before process shutdown. Do not use it for short-lived mappings.
|
||||||
class SharedPrefMap {
|
class SharedPrefMap {
|
||||||
using FileDescriptor = mozilla::ipc::FileDescriptor;
|
|
||||||
|
|
||||||
friend class SharedPrefMapBuilder;
|
friend class SharedPrefMapBuilder;
|
||||||
|
|
||||||
// Describes a block of memory within the shared memory region.
|
// Describes a block of memory within the shared memory region.
|
||||||
@@ -421,7 +419,7 @@ class SharedPrefMap {
|
|||||||
|
|
||||||
// Note: These constructors are infallible, because the preference database is
|
// Note: These constructors are infallible, because the preference database is
|
||||||
// critical to platform functionality, and we cannot operate without it.
|
// critical to platform functionality, and we cannot operate without it.
|
||||||
SharedPrefMap(const FileDescriptor&, size_t);
|
SharedPrefMap(const mozilla::ipc::SharedMemoryHandle&, size_t);
|
||||||
explicit SharedPrefMap(SharedPrefMapBuilder&&);
|
explicit SharedPrefMap(SharedPrefMapBuilder&&);
|
||||||
|
|
||||||
// Searches for the given preference in the map, and returns true if it
|
// Searches for the given preference in the map, and returns true if it
|
||||||
@@ -500,15 +498,15 @@ class SharedPrefMap {
|
|||||||
// makes its purpose slightly clearer.
|
// makes its purpose slightly clearer.
|
||||||
const SharedPrefMap& Iter() const { return *this; }
|
const SharedPrefMap& Iter() const { return *this; }
|
||||||
|
|
||||||
// Returns a copy of the read-only file descriptor which backs the shared
|
// Returns a copy of the read-only shared memory handle which backs the shared
|
||||||
// memory region for this map. The file descriptor may be passed between
|
// memory region for this map. The handle may be passed between processes, and
|
||||||
// processes, and used to construct new instances of SharedPrefMap with
|
// used to construct new instances of SharedPrefMap with the same data as this
|
||||||
// the same data as this instance.
|
// instance.
|
||||||
FileDescriptor CloneFileDescriptor() const;
|
mozilla::ipc::SharedMemoryHandle CloneHandle() const;
|
||||||
|
|
||||||
// Returns the size of the mapped memory region. This size must be passed to
|
// Returns the size of the mapped memory region. This size must be passed to
|
||||||
// the constructor when mapping the shared region in another process.
|
// the constructor when mapping the shared region in another process.
|
||||||
size_t MapSize() const { return mMap.size(); }
|
size_t MapSize() const { return mMappedMemory.size(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~SharedPrefMap() = default;
|
~SharedPrefMap() = default;
|
||||||
@@ -518,7 +516,9 @@ class SharedPrefMap {
|
|||||||
using StringTable = mozilla::dom::ipc::StringTable<T>;
|
using StringTable = mozilla::dom::ipc::StringTable<T>;
|
||||||
|
|
||||||
// Type-safe getters for values in the shared memory region:
|
// Type-safe getters for values in the shared memory region:
|
||||||
const Header& GetHeader() const { return mMap.get<Header>()[0]; }
|
const Header& GetHeader() const {
|
||||||
|
return *reinterpret_cast<const Header*>(mMappedMemory.data());
|
||||||
|
}
|
||||||
|
|
||||||
RangedPtr<const Entry> Entries() const {
|
RangedPtr<const Entry> Entries() const {
|
||||||
return {reinterpret_cast<const Entry*>(&GetHeader() + 1), EntryCount()};
|
return {reinterpret_cast<const Entry*>(&GetHeader() + 1), EntryCount()};
|
||||||
@@ -528,7 +528,7 @@ class SharedPrefMap {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
RangedPtr<const T> GetBlock(const DataBlock& aBlock) const {
|
RangedPtr<const T> GetBlock(const DataBlock& aBlock) const {
|
||||||
return RangedPtr<uint8_t>(&mMap.get<uint8_t>()[aBlock.mOffset],
|
return RangedPtr<uint8_t>(&mMappedMemory.data()[aBlock.mOffset],
|
||||||
aBlock.mSize)
|
aBlock.mSize)
|
||||||
.ReinterpretCast<const T>();
|
.ReinterpretCast<const T>();
|
||||||
}
|
}
|
||||||
@@ -549,15 +549,19 @@ class SharedPrefMap {
|
|||||||
|
|
||||||
StringTable<nsCString> KeyTable() const {
|
StringTable<nsCString> KeyTable() const {
|
||||||
auto& block = GetHeader().mKeyStrings;
|
auto& block = GetHeader().mKeyStrings;
|
||||||
return {{&mMap.get<uint8_t>()[block.mOffset], block.mSize}};
|
return {{&mMappedMemory.data()[block.mOffset], block.mSize}};
|
||||||
}
|
}
|
||||||
|
|
||||||
StringTable<nsCString> ValueTable() const {
|
StringTable<nsCString> ValueTable() const {
|
||||||
auto& block = GetHeader().mValueStrings;
|
auto& block = GetHeader().mValueStrings;
|
||||||
return {{&mMap.get<uint8_t>()[block.mOffset], block.mSize}};
|
return {{&mMappedMemory.data()[block.mOffset], block.mSize}};
|
||||||
}
|
}
|
||||||
|
|
||||||
loader::AutoMemMap mMap;
|
mozilla::ipc::SharedMemoryHandle mHandle;
|
||||||
|
// This is a leaked shared memory mapping (see the constructor definition for
|
||||||
|
// an explanation). It replaces AutoMemMap::setPersistent behavior as part of
|
||||||
|
// bug 1454816.
|
||||||
|
Span<uint8_t> mMappedMemory;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A helper class which builds the contiguous look-up table used by
|
// A helper class which builds the contiguous look-up table used by
|
||||||
@@ -587,13 +591,13 @@ class MOZ_RAII SharedPrefMapBuilder {
|
|||||||
const nsCString& aDefaultValue, const nsCString& aUserValue);
|
const nsCString& aDefaultValue, const nsCString& aUserValue);
|
||||||
|
|
||||||
// Finalizes the binary representation of the map, writes it to a shared
|
// Finalizes the binary representation of the map, writes it to a shared
|
||||||
// memory region, and then initializes the given AutoMemMap with a reference
|
// memory region, and then initializes the given SharedMemory with a reference
|
||||||
// to the read-only copy of it.
|
// to the read-only copy of it.
|
||||||
//
|
//
|
||||||
// This should generally not be used directly by callers. The
|
// This should generally not be used directly by callers. The
|
||||||
// SharedPrefMapBuilder instance should instead be passed to the SharedPrefMap
|
// SharedPrefMapBuilder instance should instead be passed to the SharedPrefMap
|
||||||
// constructor as a move reference.
|
// constructor as a move reference.
|
||||||
Result<Ok, nsresult> Finalize(loader::AutoMemMap& aMap);
|
Result<Ok, nsresult> Finalize(RefPtr<mozilla::ipc::SharedMemory>& aMap);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using StringTableEntry = mozilla::dom::ipc::StringTableEntry;
|
using StringTableEntry = mozilla::dom::ipc::StringTableEntry;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include "SocketProcessImpl.h"
|
#include "SocketProcessImpl.h"
|
||||||
|
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/shared_memory.h"
|
|
||||||
#include "base/string_util.h"
|
#include "base/string_util.h"
|
||||||
#include "mozilla/BackgroundHangMonitor.h"
|
#include "mozilla/BackgroundHangMonitor.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "SandboxInfo.h"
|
#include "SandboxInfo.h"
|
||||||
#include "SandboxLogging.h"
|
#include "SandboxLogging.h"
|
||||||
|
|
||||||
#include "base/shared_memory.h"
|
|
||||||
#include "mozilla/Array.h"
|
#include "mozilla/Array.h"
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
#include "mozilla/Omnijar.h"
|
#include "mozilla/Omnijar.h"
|
||||||
@@ -19,6 +18,7 @@
|
|||||||
#include "mozilla/StaticMutex.h"
|
#include "mozilla/StaticMutex.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
#include "mozilla/UniquePtrExtensions.h"
|
#include "mozilla/UniquePtrExtensions.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
@@ -323,7 +323,7 @@ static void AddLdLibraryEnvPaths(SandboxBroker::Policy* aPolicy) {
|
|||||||
|
|
||||||
static void AddSharedMemoryPaths(SandboxBroker::Policy* aPolicy, pid_t aPid) {
|
static void AddSharedMemoryPaths(SandboxBroker::Policy* aPolicy, pid_t aPid) {
|
||||||
std::string shmPath("/dev/shm");
|
std::string shmPath("/dev/shm");
|
||||||
if (base::SharedMemory::AppendPosixShmPrefix(&shmPath, aPid)) {
|
if (ipc::SharedMemory::AppendPosixShmPrefix(&shmPath, aPid)) {
|
||||||
aPolicy->AddPrefix(rdwrcr, shmPath.c_str());
|
aPolicy->AddPrefix(rdwrcr, shmPath.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "mozilla/CmdLineAndEnvUtils.h"
|
#include "mozilla/CmdLineAndEnvUtils.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/UniquePtrExtensions.h"
|
#include "mozilla/UniquePtrExtensions.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
@@ -187,14 +188,14 @@ static CommandLineArg<const char*> sProfile{"-profile", "profile"};
|
|||||||
|
|
||||||
static CommandLineArg<UniqueFileHandle> sIPCHandle{"-ipcHandle", "ipchandle"};
|
static CommandLineArg<UniqueFileHandle> sIPCHandle{"-ipcHandle", "ipchandle"};
|
||||||
|
|
||||||
static CommandLineArg<UniqueFileHandle> sJsInitHandle{"-jsInitHandle",
|
static CommandLineArg<mozilla::ipc::SharedMemoryHandle> sJsInitHandle{
|
||||||
"jsinithandle"};
|
"-jsInitHandle", "jsinithandle"};
|
||||||
static CommandLineArg<uint64_t> sJsInitLen{"-jsInitLen", "jsinitlen"};
|
static CommandLineArg<uint64_t> sJsInitLen{"-jsInitLen", "jsinitlen"};
|
||||||
static CommandLineArg<UniqueFileHandle> sPrefsHandle{"-prefsHandle",
|
static CommandLineArg<mozilla::ipc::SharedMemoryHandle> sPrefsHandle{
|
||||||
"prefshandle"};
|
"-prefsHandle", "prefshandle"};
|
||||||
static CommandLineArg<uint64_t> sPrefsLen{"-prefsLen", "prefslen"};
|
static CommandLineArg<uint64_t> sPrefsLen{"-prefsLen", "prefslen"};
|
||||||
static CommandLineArg<UniqueFileHandle> sPrefMapHandle{"-prefMapHandle",
|
static CommandLineArg<mozilla::ipc::SharedMemoryHandle> sPrefMapHandle{
|
||||||
"prefmaphandle"};
|
"-prefMapHandle", "prefmaphandle"};
|
||||||
static CommandLineArg<uint64_t> sPrefMapSize{"-prefMapSize", "prefmapsize"};
|
static CommandLineArg<uint64_t> sPrefMapSize{"-prefMapSize", "prefmapsize"};
|
||||||
|
|
||||||
static CommandLineArg<uint64_t> sSandboxingKind{"-sandboxingKind",
|
static CommandLineArg<uint64_t> sSandboxingKind{"-sandboxingKind",
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ RefPtr<WaylandShmPool> WaylandShmPool::Create(nsWaylandDisplay* aWaylandDisplay,
|
|||||||
|
|
||||||
RefPtr<WaylandShmPool> shmPool = new WaylandShmPool();
|
RefPtr<WaylandShmPool> shmPool = new WaylandShmPool();
|
||||||
|
|
||||||
shmPool->mShm = MakeUnique<base::SharedMemory>();
|
shmPool->mShm = MakeRefPtr<ipc::SharedMemory>();
|
||||||
if (!shmPool->mShm->Create(aSize)) {
|
if (!shmPool->mShm->Create(aSize)) {
|
||||||
NS_WARNING("WaylandShmPool: Unable to allocate shared memory!");
|
NS_WARNING("WaylandShmPool: Unable to allocate shared memory!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -77,7 +77,7 @@ void* WaylandShmPool::GetImageData() {
|
|||||||
NS_WARNING("WaylandShmPool: Failed to map Shm!");
|
NS_WARNING("WaylandShmPool: Failed to map Shm!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
mImageData = mShm->memory();
|
mImageData = mShm->Memory();
|
||||||
return mImageData;
|
return mImageData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,13 @@
|
|||||||
#include "DMABufSurface.h"
|
#include "DMABufSurface.h"
|
||||||
#include "GLContext.h"
|
#include "GLContext.h"
|
||||||
#include "MozFramebuffer.h"
|
#include "MozFramebuffer.h"
|
||||||
|
#include "mozilla/ipc/SharedMemory.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "mozilla/gfx/Types.h"
|
#include "mozilla/gfx/Types.h"
|
||||||
#include "mozilla/Mutex.h"
|
#include "mozilla/Mutex.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsWaylandDisplay.h"
|
#include "nsWaylandDisplay.h"
|
||||||
#include "base/shared_memory.h"
|
|
||||||
|
|
||||||
namespace mozilla::widget {
|
namespace mozilla::widget {
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ class WaylandShmPool {
|
|||||||
|
|
||||||
wl_shm_pool* mShmPool = nullptr;
|
wl_shm_pool* mShmPool = nullptr;
|
||||||
void* mImageData = nullptr;
|
void* mImageData = nullptr;
|
||||||
UniquePtr<base::SharedMemory> mShm;
|
RefPtr<ipc::SharedMemory> mShm;
|
||||||
int mSize = 0;
|
int mSize = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user