From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- ipc/glue/RawShmem.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 ipc/glue/RawShmem.cpp (limited to 'ipc/glue/RawShmem.cpp') diff --git a/ipc/glue/RawShmem.cpp b/ipc/glue/RawShmem.cpp new file mode 100644 index 0000000000..bfb47c0832 --- /dev/null +++ b/ipc/glue/RawShmem.cpp @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "RawShmem.h" +#include "mozilla/ipc/ProtocolUtils.h" + +namespace mozilla::ipc { + +UnsafeSharedMemoryHandle::UnsafeSharedMemoryHandle() + : mHandle(ipc::SharedMemoryBasic::NULLHandle()), mSize(0) {} + +UnsafeSharedMemoryHandle::UnsafeSharedMemoryHandle( + UnsafeSharedMemoryHandle&& aOther) noexcept + : mHandle(std::move(aOther.mHandle)), mSize(aOther.mSize) { + aOther.mHandle = ipc::SharedMemoryBasic::NULLHandle(); + aOther.mSize = 0; +} + +UnsafeSharedMemoryHandle& UnsafeSharedMemoryHandle::operator=( + UnsafeSharedMemoryHandle&& aOther) noexcept { + if (this == &aOther) { + return *this; + } + + mHandle = std::move(aOther.mHandle); + mSize = aOther.mSize; + aOther.mHandle = ipc::SharedMemoryBasic::NULLHandle(); + aOther.mSize = 0; + return *this; +} + +Maybe> +UnsafeSharedMemoryHandle::CreateAndMap(size_t aSize) { + if (aSize == 0) { + return Some(std::make_pair(UnsafeSharedMemoryHandle(), + WritableSharedMemoryMapping())); + } + + RefPtr shm = MakeAndAddRef(); + if (NS_WARN_IF(!shm->Create(aSize)) || NS_WARN_IF(!shm->Map(aSize))) { + return Nothing(); + } + + // TODO(bug 1797039): At the moment the handle/mapping distinction is + // implemented on top of a single class SharedMemoryBasic. It leads to a few + // awkward or sub-optimal things such as how the following few lines clone + // then close the handle. It would be better to separate the underlying + // implementation or steal the handle to avoid cloning it. + auto handle = shm->CloneHandle(); + + shm->CloseHandle(); + auto size = shm->Size(); + + return Some(std::make_pair(UnsafeSharedMemoryHandle(std::move(handle), size), + WritableSharedMemoryMapping(std::move(shm)))); +} + +WritableSharedMemoryMapping::WritableSharedMemoryMapping( + RefPtr&& aRef) + : mRef(aRef) {} + +Maybe WritableSharedMemoryMapping::Open( + UnsafeSharedMemoryHandle aHandle) { + if (aHandle.mSize == 0) { + return Some(WritableSharedMemoryMapping(nullptr)); + } + + RefPtr shm = MakeAndAddRef(); + if (NS_WARN_IF(!shm->SetHandle(std::move(aHandle.mHandle), + ipc::SharedMemory::RightsReadWrite)) || + NS_WARN_IF(!shm->Map(aHandle.mSize))) { + return Nothing(); + } + + shm->CloseHandle(); + + return Some(WritableSharedMemoryMapping(std::move(shm))); +} + +size_t WritableSharedMemoryMapping::Size() const { + if (!mRef) { + return 0; + } + + return mRef->Size(); +} + +Span WritableSharedMemoryMapping::Bytes() { + if (!mRef) { + return Span(); + } + + uint8_t* mem = static_cast(mRef->memory()); + return Span(mem, mRef->Size()); +} + +} // namespace mozilla::ipc + +namespace IPC { +auto ParamTraits::Write( + IPC::MessageWriter* aWriter, paramType&& aVar) -> void { + IPC::WriteParam(aWriter, std::move(aVar.mHandle)); + IPC::WriteParam(aWriter, aVar.mSize); +} + +auto ParamTraits::Read( + IPC::MessageReader* aReader, paramType* aVar) -> bool { + return IPC::ReadParam(aReader, &aVar->mHandle) && + IPC::ReadParam(aReader, &aVar->mSize); +} + +} // namespace IPC -- cgit v1.2.3