Backed out 2 changesets (bug 1943998) for causing wd failures @ phases.py CLOSED...
[gecko.git] / ipc / glue / SharedMemoryHandle.cpp
blob167f2f0798dcfe57ecf8cec04bdb975cc085b7f7
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* This source code was derived from Chromium code, and as such is also subject
8 * to the [Chromium license](ipc/chromium/src/LICENSE). */
10 #include "mozilla/ipc/SharedMemoryHandle.h"
11 #include "mozilla/ipc/SharedMemoryMapping.h"
12 #include "SharedMemoryPlatform.h"
14 #include "chrome/common/ipc_message_utils.h"
15 #include "mozilla/Atomics.h"
16 #include "nsDebug.h"
17 #include "nsIMemoryReporter.h"
19 namespace mozilla::ipc::shared_memory {
21 // Implementation of the shared memory logger in SharedMemoryPlatform.h.
22 LazyLogModule gSharedMemoryLog{"SharedMemory"};
24 class AllocationReporter final : public nsIMemoryReporter {
25 ~AllocationReporter() = default;
27 public:
28 static Atomic<uint64_t> allocated;
30 NS_DECL_THREADSAFE_ISUPPORTS
32 NS_IMETHOD
33 CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
34 bool aAnonymize) override {
35 MOZ_COLLECT_REPORT(
36 "shmem-allocated", KIND_OTHER, UNITS_BYTES, allocated,
37 "Memory shared with other processes that is accessible (but not "
38 "necessarily mapped).");
40 return NS_OK;
44 Atomic<uint64_t> AllocationReporter::allocated;
46 NS_IMPL_ISUPPORTS(AllocationReporter, nsIMemoryReporter)
48 static void RegisterMemoryReporter() {
49 static Atomic<bool> registered;
50 if (registered.compareExchange(false, true)) {
51 RegisterStrongMemoryReporter(new AllocationReporter());
55 HandleBase::HandleBase() { RegisterMemoryReporter(); }
57 HandleBase::~HandleBase() {
58 MOZ_ASSERT(AllocationReporter::allocated >= mSize,
59 "Can't destroy more than allocated");
60 AllocationReporter::allocated -= mSize;
61 mHandle = nullptr;
62 mSize = 0;
65 HandleBase HandleBase::Clone() const {
66 HandleBase hb;
67 hb.mHandle = Platform::CloneHandle(mHandle);
68 if (hb.mHandle) {
69 hb.mSize = mSize;
70 // TODO more intelligently handle clones to not count as addition
71 // allocations?
72 AllocationReporter::allocated += mSize;
74 return hb;
77 void HandleBase::ToMessageWriter(IPC::MessageWriter* aWriter) && {
78 WriteParam(aWriter, std::move(mHandle));
79 WriteParam(aWriter, std::exchange(mSize, 0));
82 bool HandleBase::FromMessageReader(IPC::MessageReader* aReader) {
83 mozilla::ipc::shared_memory::PlatformHandle handle;
84 if (!ReadParam(aReader, &handle)) {
85 return false;
87 if (handle && !Platform::IsSafeToMap(handle)) {
88 return false;
90 mHandle = std::move(handle);
91 if (!ReadParam(aReader, &mSize)) {
92 return false;
94 mozilla::ipc::shared_memory::AllocationReporter::allocated += mSize;
95 return true;
98 Mapping Handle::Map(void* aFixedAddress) const {
99 return Mapping(*this, aFixedAddress);
102 ReadOnlyMapping ReadOnlyHandle::Map(void* aFixedAddress) const {
103 return ReadOnlyMapping(*this, aFixedAddress);
106 FreezableHandle::~FreezableHandle() {
107 NS_WARNING_ASSERTION(!IsValid(), "freezable shared memory was never frozen");
110 Handle FreezableHandle::WontFreeze() && {
111 return std::move(*this).ConvertTo<Handle>();
114 ReadOnlyHandle FreezableHandle::Freeze() && {
115 DebugOnly<const uint64_t> previous_size = Size();
116 if (Platform::Freeze(*this)) {
117 MOZ_ASSERT(Size() == previous_size);
118 return std::move(*this).ConvertTo<ReadOnlyHandle>();
120 return nullptr;
123 FreezableMapping FreezableHandle::Map(void* aFixedAddress) && {
124 return FreezableMapping(std::move(*this), aFixedAddress);
127 Handle Create(uint64_t aSize) {
128 Handle h;
129 const auto success = Platform::Create(h, aSize);
130 MOZ_ASSERT(success == h.IsValid());
131 if (success) {
132 MOZ_ASSERT(aSize == h.Size());
133 AllocationReporter::allocated += h.Size();
135 return h;
138 FreezableHandle CreateFreezable(uint64_t aSize) {
139 FreezableHandle h;
140 const auto success = Platform::CreateFreezable(h, aSize);
141 MOZ_ASSERT(success == h.IsValid());
142 if (success) {
143 MOZ_ASSERT(aSize == h.Size());
144 AllocationReporter::allocated += h.Size();
146 return h;
149 } // namespace mozilla::ipc::shared_memory
151 namespace IPC {
153 void ParamTraits<mozilla::ipc::shared_memory::Handle>::Write(
154 MessageWriter* aWriter, mozilla::ipc::shared_memory::Handle&& aParam) {
155 std::move(aParam).ToMessageWriter(aWriter);
158 bool ParamTraits<mozilla::ipc::shared_memory::Handle>::Read(
159 MessageReader* aReader, mozilla::ipc::shared_memory::Handle* aResult) {
160 return aResult->FromMessageReader(aReader);
163 void ParamTraits<mozilla::ipc::shared_memory::ReadOnlyHandle>::Write(
164 MessageWriter* aWriter,
165 mozilla::ipc::shared_memory::ReadOnlyHandle&& aParam) {
166 std::move(aParam).ToMessageWriter(aWriter);
169 bool ParamTraits<mozilla::ipc::shared_memory::ReadOnlyHandle>::Read(
170 MessageReader* aReader,
171 mozilla::ipc::shared_memory::ReadOnlyHandle* aResult) {
172 return aResult->FromMessageReader(aReader);
175 } // namespace IPC