Bug 1734739 - Part 1: Stop requiring otherpid for ShareTo, r=handyman

Differential Revision: https://phabricator.services.mozilla.com/D128218
This commit is contained in:
Nika Layzell 2021-11-24 17:56:00 +00:00
parent ab9c0e444e
commit 26555d958a
32 changed files with 91 additions and 110 deletions

View File

@ -2623,7 +2623,7 @@ bool ContentParent::LaunchSubprocessResolve(bool aIsSync,
#ifdef MOZ_CODE_COVERAGE
Unused << SendShareCodeCoverageMutex(
CodeCoverageHandler::Get()->GetMutexHandle(procId));
CodeCoverageHandler::Get()->GetMutexHandle());
#endif
// We must be in the LAUNCHING state still. If we've somehow already been
@ -2974,8 +2974,7 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
Maybe<SharedMemoryHandle> sharedUASheetHandle;
uintptr_t sharedUASheetAddress = sheetCache->GetSharedMemoryAddress();
SharedMemoryHandle handle;
if (sheetCache->ShareToProcess(OtherPid(), &handle)) {
if (SharedMemoryHandle handle = sheetCache->CloneHandle()) {
sharedUASheetHandle.emplace(std::move(handle));
} else {
sharedUASheetAddress = 0;

View File

@ -37,7 +37,8 @@ bool CanvasEventRingBuffer::InitWriter(
return false;
}
if (NS_WARN_IF(!mSharedMemory->ShareToProcess(aOtherPid, aReadHandle))) {
*aReadHandle = mSharedMemory->CloneHandle();
if (NS_WARN_IF(!*aReadHandle)) {
return false;
}
@ -64,14 +65,14 @@ bool CanvasEventRingBuffer::InitWriter(
mReaderSemaphore.reset(
CrossProcessSemaphore::Create("SharedMemoryStreamParent", 0));
*aReaderSem = mReaderSemaphore->ShareToProcess(aOtherPid);
*aReaderSem = mReaderSemaphore->CloneHandle();
mReaderSemaphore->CloseHandle();
if (!IsHandleValid(*aReaderSem)) {
return false;
}
mWriterSemaphore.reset(
CrossProcessSemaphore::Create("SharedMemoryStreamChild", 0));
*aWriterSem = mWriterSemaphore->ShareToProcess(aOtherPid);
*aWriterSem = mWriterSemaphore->CloneHandle();
mWriterSemaphore->CloseHandle();
if (!IsHandleValid(*aWriterSem)) {
return false;

View File

@ -195,8 +195,8 @@ uint8_t* SourceSurfaceSharedData::GetDataInternal() const {
return static_cast<uint8_t*>(mBuf->memory());
}
nsresult SourceSurfaceSharedData::ShareToProcess(
base::ProcessId aPid, SharedMemoryBasic::Handle& aHandle) {
nsresult SourceSurfaceSharedData::CloneHandle(
SharedMemoryBasic::Handle& aHandle) {
MutexAutoLock lock(mMutex);
MOZ_ASSERT(mHandleCount > 0);
@ -204,8 +204,8 @@ nsresult SourceSurfaceSharedData::ShareToProcess(
return NS_ERROR_NOT_AVAILABLE;
}
bool shared = mBuf->ShareToProcess(aPid, &aHandle);
if (MOZ_UNLIKELY(!shared)) {
aHandle = mBuf->CloneHandle();
if (MOZ_UNLIKELY(!aHandle)) {
return NS_ERROR_FAILURE;
}

View File

@ -200,8 +200,7 @@ class SourceSurfaceSharedData : public DataSourceSurface {
* NS_ERROR_NOT_AVAILABLE -- handle was closed, need to reallocate.
* NS_ERROR_FAILURE -- failed to create a handle to share.
*/
nsresult ShareToProcess(base::ProcessId aPid,
SharedMemoryBasic::Handle& aHandle);
nsresult CloneHandle(SharedMemoryBasic::Handle& aHandle);
/**
* Indicates the buffer is not expected to be shared with any more processes.
@ -225,7 +224,7 @@ class SourceSurfaceSharedData : public DataSourceSurface {
/**
* Allocate a new shared memory buffer so that we can get a new handle for
* sharing to new processes. ShareToProcess must have failed with
* sharing to new processes. CloneHandle must have failed with
* NS_ERROR_NOT_AVAILABLE in order for this to be safe to call. Returns true
* if the operation succeeds. If it fails, there is no state change.
*/

View File

@ -1682,7 +1682,7 @@ bool CrossProcessSemaphoreReadLock::Serialize(ReadLockDescriptor& aOutput,
base::ProcessId aOther) {
if (!mShared && IsValid()) {
aOutput = ReadLockDescriptor(
CrossProcessSemaphoreDescriptor(mSemaphore->ShareToProcess(aOther)));
CrossProcessSemaphoreDescriptor(mSemaphore->CloneHandle()));
mSemaphore->CloseHandle();
mShared = true;
return true;

View File

@ -176,7 +176,8 @@ CompositorManagerChild::CompositorManagerChild(CompositorManagerParent* aParent,
: mProcessToken(aProcessToken),
mNamespace(aNamespace),
mResourceId(0),
mCanSend(false) {
mCanSend(false),
mSameProcess(true) {
MOZ_ASSERT(aParent);
SetOtherProcessId(base::GetCurrentProcId());
@ -196,7 +197,8 @@ CompositorManagerChild::CompositorManagerChild(
: mProcessToken(aProcessToken),
mNamespace(aNamespace),
mResourceId(0),
mCanSend(false) {
mCanSend(false),
mSameProcess(false) {
if (NS_WARN_IF(!aEndpoint.Bind(this))) {
return;
}

View File

@ -58,6 +58,11 @@ class CompositorManagerChild : public PCompositorManagerChild {
return mCanSend;
}
bool SameProcess() const {
MOZ_ASSERT(NS_IsMainThread());
return mSameProcess;
}
uint32_t GetNextResourceId() {
MOZ_ASSERT(NS_IsMainThread());
return ++mResourceId;
@ -107,6 +112,7 @@ class CompositorManagerChild : public PCompositorManagerChild {
uint32_t mNamespace;
uint32_t mResourceId;
bool mCanSend;
bool mSameProcess;
};
} // namespace layers

View File

@ -207,8 +207,7 @@ nsresult SharedSurfacesChild::ShareInternal(SourceSurfaceSharedData* aSurface,
// If we live in the same process, then it is a simple matter of directly
// asking the parent instance to store a pointer to the same data, no need
// to map the data into our memory space twice.
auto pid = manager->OtherPid();
if (pid == base::GetCurrentProcId()) {
if (manager->SameProcess()) {
SharedSurfacesParent::AddSameProcess(data->Id(), aSurface);
data->MarkShared();
*aUserData = data;
@ -219,7 +218,7 @@ nsresult SharedSurfacesChild::ShareInternal(SourceSurfaceSharedData* aSurface,
// be available -- it will only be available if it is either not yet finalized
// and/or if it has been finalized but never used for drawing in process.
ipc::SharedMemoryBasic::Handle handle = ipc::SharedMemoryBasic::NULLHandle();
nsresult rv = aSurface->ShareToProcess(pid, handle);
nsresult rv = aSurface->CloneHandle(handle);
if (rv == NS_ERROR_NOT_AVAILABLE) {
// It is at least as expensive to copy the image to the GPU process if we
// have already closed the handle necessary to share, but if we reallocate
@ -229,7 +228,7 @@ nsresult SharedSurfacesChild::ShareInternal(SourceSurfaceSharedData* aSurface,
}
// Reattempt the sharing of the handle to the GPU process.
rv = aSurface->ShareToProcess(pid, handle);
rv = aSurface->CloneHandle(handle);
}
if (NS_WARN_IF(NS_FAILED(rv))) {

View File

@ -352,7 +352,7 @@ void nsHyphenationManager::ShareHyphDictToProcess(
return;
}
hyph->ShareToProcess(aPid, aOutHandle, aOutSize);
hyph->CloneHandle(aOutHandle, aOutSize);
}
size_t nsHyphenationManager::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) {

View File

@ -487,9 +487,8 @@ void nsHyphenator::HyphenateWord(const nsAString& aString, uint32_t aStart,
}
}
void nsHyphenator::ShareToProcess(base::ProcessId aPid,
base::SharedMemoryHandle* aOutHandle,
uint32_t* aOutSize) {
void nsHyphenator::CloneHandle(base::SharedMemoryHandle* aOutHandle,
uint32_t* aOutSize) {
// 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
// for this to be a fatal error.

View File

@ -41,8 +41,7 @@ class nsHyphenator {
nsresult Hyphenate(const nsAString& aText, nsTArray<bool>& aHyphens);
void ShareToProcess(base::ProcessId aPid,
base::SharedMemoryHandle* aOutHandle, uint32_t* aOutSize);
void CloneHandle(base::SharedMemoryHandle* aOutHandle, uint32_t* aOutSize);
private:
~nsHyphenator() = default;

View File

@ -86,13 +86,13 @@ class CrossProcessMutex {
void Unlock();
/**
* ShareToProcess
* CloneHandle
* This function is called to generate a serializable structure that can
* be sent to the specified process and opened on the other side.
*
* @returns A handle that can be shared to another process
*/
CrossProcessMutexHandle ShareToProcess(base::ProcessId aTargetPid);
CrossProcessMutexHandle CloneHandle();
private:
friend struct IPC::ParamTraits<CrossProcessMutex>;

View File

@ -124,12 +124,14 @@ void CrossProcessMutex::Unlock() {
pthread_mutex_unlock(mMutex);
}
CrossProcessMutexHandle CrossProcessMutex::ShareToProcess(
base::ProcessId aTargetPid) {
CrossProcessMutexHandle CrossProcessMutex::CloneHandle() {
CrossProcessMutexHandle result = ipc::SharedMemoryBasic::NULLHandle();
if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aTargetPid, &result)) {
MOZ_CRASH();
if (mSharedBuffer) {
result = mSharedBuffer->CloneHandle();
if (!result) {
MOZ_CRASH();
}
}
return result;

View File

@ -36,8 +36,7 @@ void CrossProcessMutex::Unlock() {
"aborted by now!");
}
CrossProcessMutexHandle CrossProcessMutex::ShareToProcess(
base::ProcessId aTargetPid) {
CrossProcessMutexHandle CrossProcessMutex::CloneHandle() {
MOZ_CRASH(
"Cross-process mutices not allowed on this platform - woah! We should've "
"aborted by now!");

View File

@ -53,8 +53,7 @@ void CrossProcessMutex::Unlock() {
::ReleaseMutex(mMutex);
}
CrossProcessMutexHandle CrossProcessMutex::ShareToProcess(
base::ProcessId aTargetPid) {
CrossProcessMutexHandle CrossProcessMutex::CloneHandle() {
HANDLE newHandle;
if (!::DuplicateHandle(GetCurrentProcess(), mMutex, GetCurrentProcess(),
&newHandle, 0, false, DUPLICATE_SAME_ACCESS)) {

View File

@ -85,13 +85,13 @@ class CrossProcessSemaphore {
void Signal();
/**
* ShareToProcess
* CloneHandle
* This function is called to generate a serializable structure that can
* be sent to the specified process and opened on the other side.
*
* @returns A handle that can be shared to another process
*/
CrossProcessSemaphoreHandle ShareToProcess(base::ProcessId aTargetPid);
CrossProcessSemaphoreHandle CloneHandle();
void CloseHandle();

View File

@ -146,12 +146,14 @@ void CrossProcessSemaphore::Signal() {
sem_post(mSemaphore);
}
CrossProcessSemaphoreHandle CrossProcessSemaphore::ShareToProcess(
base::ProcessId aTargetPid) {
CrossProcessSemaphoreHandle CrossProcessSemaphore::CloneHandle() {
CrossProcessSemaphoreHandle result = ipc::SharedMemoryBasic::NULLHandle();
if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aTargetPid, &result)) {
MOZ_CRASH();
if (mSharedBuffer) {
result = mSharedBuffer->CloneHandle();
if (!result) {
MOZ_CRASH();
}
}
return result;

View File

@ -48,8 +48,7 @@ void CrossProcessSemaphore::Signal() {
"should've aborted by now!");
}
CrossProcessSemaphoreHandle CrossProcessSemaphore::ShareToProcess(
base::ProcessId aTargetPid) {
CrossProcessSemaphoreHandle CrossProcessSemaphore::CloneHandle() {
MOZ_CRASH(
"Cross-process semaphores not allowed on this platform - woah! We "
"should've aborted by now!");

View File

@ -65,8 +65,7 @@ void CrossProcessSemaphore::Signal() {
::ReleaseSemaphore(mSemaphore, 1, nullptr);
}
CrossProcessSemaphoreHandle CrossProcessSemaphore::ShareToProcess(
base::ProcessId aTargetPid) {
CrossProcessSemaphoreHandle CrossProcessSemaphore::CloneHandle() {
HANDLE newHandle;
bool succeeded =
::DuplicateHandle(GetCurrentProcess(), mSemaphore, GetCurrentProcess(),

View File

@ -717,18 +717,8 @@ Shmem::SharedMemory* IToplevelProtocol::CreateSharedMemory(
int32_t id = NextId();
Shmem shmem(Shmem::PrivateIPDLCaller(), segment.get(), id);
base::ProcessId pid =
#ifdef ANDROID
// We use OtherPidMaybeInvalid() because on Android this method is
// actually called on an unconnected protocol, but Android's shared memory
// implementation doesn't actually use the PID.
OtherPidMaybeInvalid();
#else
OtherPid();
#endif
UniquePtr<Message> descriptor =
shmem.ShareTo(Shmem::PrivateIPDLCaller(), pid, MSG_ROUTING_CONTROL);
shmem.MkCreatedMessage(Shmem::PrivateIPDLCaller(), MSG_ROUTING_CONTROL);
if (!descriptor) {
return nullptr;
}
@ -762,7 +752,7 @@ bool IToplevelProtocol::DestroySharedMemory(Shmem& shmem) {
}
UniquePtr<Message> descriptor =
shmem.UnshareFrom(Shmem::PrivateIPDLCaller(), MSG_ROUTING_CONTROL);
shmem.MkDestroyedMessage(Shmem::PrivateIPDLCaller(), MSG_ROUTING_CONTROL);
MOZ_ASSERT(mShmemMap.Contains(aId),
"Attempting to remove an ID not in the shmem map");

View File

@ -57,8 +57,7 @@ class SharedMemory {
virtual SharedMemoryType Type() const = 0;
virtual bool ShareHandle(base::ProcessId aProcessId,
IPC::Message* aMessage) = 0;
virtual bool WriteHandle(IPC::Message* aMessage) = 0;
virtual bool ReadHandle(const IPC::Message* aMessage,
PickleIterator* aIter) = 0;
@ -119,14 +118,13 @@ class SharedMemoryCommon : public SharedMemory {
public:
typedef HandleImpl Handle;
virtual bool ShareToProcess(base::ProcessId aProcessId, Handle* aHandle) = 0;
virtual Handle CloneHandle() = 0;
virtual bool IsHandleValid(const Handle& aHandle) const = 0;
virtual bool SetHandle(Handle aHandle, OpenRights aRights) = 0;
virtual bool ShareHandle(base::ProcessId aProcessId,
IPC::Message* aMessage) override {
Handle handle;
if (!ShareToProcess(aProcessId, &handle)) {
virtual bool WriteHandle(IPC::Message* aMessage) override {
Handle handle = CloneHandle();
if (!handle) {
return false;
}
IPC::WriteParam(aMessage, std::move(handle));

View File

@ -97,18 +97,16 @@ void* SharedMemoryBasic::FindFreeAddressSpace(size_t size) {
return memory != (void*)-1 ? memory : NULL;
}
bool SharedMemoryBasic::ShareToProcess(base::ProcessId /*unused*/,
Handle* aNewHandle) {
auto SharedMemoryBasic::CloneHandle() -> Handle {
MOZ_ASSERT(mShmFd >= 0, "Should have been Create()d by now");
int shmfdDup = dup(mShmFd);
if (-1 == shmfdDup) {
LogError("ShmemAndroid::ShareToProcess()");
return false;
LogError("ShmemAndroid::CloneHandle()");
return nullptr;
}
*aNewHandle = mozilla::UniqueFileHandle(shmfdDup);
return true;
return mozilla::UniqueFileHandle(shmfdDup);
}
void SharedMemoryBasic::Unmap() {

View File

@ -55,8 +55,7 @@ class SharedMemoryBasic final
return aHandle != nullptr;
}
virtual bool ShareToProcess(base::ProcessId aProcessId,
Handle* aNewHandle) override;
virtual Handle CloneHandle() override;
private:
~SharedMemoryBasic();

View File

@ -71,11 +71,7 @@ class SharedMemoryBasic final
return base::SharedMemory::IsHandleValid(aHandle);
}
virtual bool ShareToProcess(base::ProcessId aProcessId,
Handle* new_handle) override {
*new_handle = mSharedMemory.CloneHandle();
return base::SharedMemory::IsHandleValid(*new_handle);
}
virtual Handle CloneHandle() override { return mSharedMemory.CloneHandle(); }
static void* FindFreeAddressSpace(size_t size) {
return base::SharedMemory::FindFreeAddressSpace(size);

View File

@ -59,8 +59,7 @@ class SharedMemoryBasic final
virtual bool IsHandleValid(const Handle& aHandle) const override;
virtual bool ShareToProcess(base::ProcessId aProcessId,
Handle* aNewHandle) override;
virtual Handle CloneHandle() override;
private:
~SharedMemoryBasic();

View File

@ -137,9 +137,8 @@ void* SharedMemoryBasic::FindFreeAddressSpace(size_t size) {
return toPointer(address);
}
bool SharedMemoryBasic::ShareToProcess(base::ProcessId pid, Handle* aNewHandle) {
*aNewHandle = mozilla::RetainMachSendRight(mPort.get());
return *aNewHandle != nullptr;
auto SharedMemoryBasic::CloneHandle() -> Handle {
return mozilla::RetainMachSendRight(mPort.get());
}
void SharedMemoryBasic::Unmap() {

View File

@ -416,13 +416,12 @@ void Shmem::Dealloc(PrivateIPDLCaller, SharedMemory* aSegment) {
#endif // if defined(DEBUG)
UniquePtr<IPC::Message> Shmem::ShareTo(PrivateIPDLCaller,
base::ProcessId aTargetPid,
int32_t routingId) {
UniquePtr<IPC::Message> Shmem::MkCreatedMessage(PrivateIPDLCaller,
int32_t routingId) {
AssertInvariants();
auto msg = MakeUnique<ShmemCreated>(routingId, mId, mSize, mSegment->Type());
if (!mSegment->ShareHandle(aTargetPid, msg.get())) {
if (!mSegment->WriteHandle(msg.get())) {
return nullptr;
}
// close the handle to the segment after it is shared
@ -430,8 +429,8 @@ UniquePtr<IPC::Message> Shmem::ShareTo(PrivateIPDLCaller,
return msg;
}
UniquePtr<IPC::Message> Shmem::UnshareFrom(PrivateIPDLCaller,
int32_t routingId) {
UniquePtr<IPC::Message> Shmem::MkDestroyedMessage(PrivateIPDLCaller,
int32_t routingId) {
AssertInvariants();
return MakeUnique<ShmemDestroyed>(routingId, mId);
}

View File

@ -156,23 +156,24 @@ class Shmem final {
bool aUnsafe,
bool aProtect = false);
// Prepare this to be shared with |aProcess|. Return an IPC message
// that contains enough information for the other process to map
// this segment in OpenExisting() below. Return a new message if
// successful (owned by the caller), nullptr if not.
UniquePtr<IPC::Message> ShareTo(PrivateIPDLCaller, base::ProcessId aTargetPid,
int32_t routingId);
// Prepare this to be shared with another process. Return an IPC message that
// contains enough information for the other process to map this segment in
// OpenExisting() below. Return a new message if successful (owned by the
// caller), nullptr if not.
UniquePtr<IPC::Message> MkCreatedMessage(PrivateIPDLCaller,
int32_t routingId);
// Stop sharing this with |aTargetPid|. Return an IPC message that
// Stop sharing this with another process. Return an IPC message that
// contains enough information for the other process to unmap this
// segment. Return a new message if successful (owned by the
// caller), nullptr if not.
UniquePtr<IPC::Message> UnshareFrom(PrivateIPDLCaller, int32_t routingId);
UniquePtr<IPC::Message> MkDestroyedMessage(PrivateIPDLCaller,
int32_t routingId);
// Return a SharedMemory instance in this process using the
// descriptor shared to us by the process that created the
// underlying OS shmem resource. The contents of the descriptor
// depend on the type of SharedMemory that was passed to us.
// Return a SharedMemory instance in this process using the descriptor shared
// to us by the process that created the underlying OS shmem resource. The
// contents of the descriptor depend on the type of SharedMemory that was
// passed to us.
static already_AddRefed<SharedMemory> OpenExisting(
PrivateIPDLCaller, const IPC::Message& aDescriptor, id_t* aId,
bool aProtect = false);

View File

@ -685,13 +685,12 @@ bool GlobalStyleSheetCache::AffectedByPref(const nsACString& aPref) {
}
}
bool GlobalStyleSheetCache::ShareToProcess(base::ProcessId aProcessId,
base::SharedMemoryHandle* aHandle) {
base::SharedMemoryHandle GlobalStyleSheetCache::CloneHandle() {
MOZ_ASSERT(XRE_IsParentProcess());
if (sSharedMemory) {
*aHandle = sSharedMemory->CloneHandle();
return sSharedMemory->CloneHandle();
}
return !!*aHandle;
return nullptr;
}
StaticRefPtr<GlobalStyleSheetCache> GlobalStyleSheetCache::gStyleCache;

View File

@ -71,8 +71,7 @@ class GlobalStyleSheetCache final : public nsIObserver,
// Obtain a shared memory handle for the shared UA sheets to pass into a
// content process. Called by ContentParent::InitInternal shortly after
// a content process has been created.
bool ShareToProcess(base::ProcessId aProcessId,
base::SharedMemoryHandle* aHandle);
base::SharedMemoryHandle CloneHandle();
// Returns the address of the shared memory segment that holds the shared UA
// sheets.

View File

@ -153,6 +153,6 @@ CodeCoverageHandler* CodeCoverageHandler::Get() {
CrossProcessMutex* CodeCoverageHandler::GetMutex() { return &mGcovLock; }
CrossProcessMutexHandle CodeCoverageHandler::GetMutexHandle(int aProcId) {
return mGcovLock.ShareToProcess(aProcId);
CrossProcessMutexHandle CodeCoverageHandler::GetMutexHandle() {
return mGcovLock.CloneHandle();
}

View File

@ -17,7 +17,7 @@ class CodeCoverageHandler {
static void Init(CrossProcessMutexHandle aHandle);
static CodeCoverageHandler* Get();
CrossProcessMutex* GetMutex();
CrossProcessMutexHandle GetMutexHandle(int aProcId);
CrossProcessMutexHandle GetMutexHandle();
static void FlushCounters(const bool initialized = false);
static void FlushCountersSignalHandler(int);