Bug 1841281 - Disable test_basics.html on mac debug and windows for frequent failures...
[gecko.git] / dom / file / MemoryBlobImpl.h
blob29d812feee2b353978bc75cbfcbb0794bea31fec
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 #ifndef mozilla_dom_MemoryBlobImpl_h
8 #define mozilla_dom_MemoryBlobImpl_h
10 #include "mozilla/dom/BaseBlobImpl.h"
11 #include "mozilla/LinkedList.h"
12 #include "mozilla/StaticMutex.h"
13 #include "mozilla/StaticPtr.h"
14 #include "mozilla/StreamBufferSource.h"
15 #include "nsCOMPtr.h"
16 #include "nsICloneableInputStream.h"
17 #include "nsIInputStream.h"
18 #include "nsIIPCSerializableInputStream.h"
19 #include "nsISeekableStream.h"
21 namespace mozilla::dom {
23 class MemoryBlobImpl final : public BaseBlobImpl {
24 public:
25 NS_INLINE_DECL_REFCOUNTING_INHERITED(MemoryBlobImpl, BaseBlobImpl)
27 // File constructor.
28 static already_AddRefed<MemoryBlobImpl> CreateWithLastModifiedNow(
29 void* aMemoryBuffer, uint64_t aLength, const nsAString& aName,
30 const nsAString& aContentType, RTPCallerType aRTPCallerType);
32 // File constructor with custom lastModified attribue value. You should
33 // probably use CreateWithLastModifiedNow() instead of this one.
34 static already_AddRefed<MemoryBlobImpl> CreateWithCustomLastModified(
35 void* aMemoryBuffer, uint64_t aLength, const nsAString& aName,
36 const nsAString& aContentType, int64_t aLastModifiedDate);
38 // Blob constructor.
39 MemoryBlobImpl(void* aMemoryBuffer, uint64_t aLength,
40 const nsAString& aContentType)
41 : BaseBlobImpl(aContentType, aLength),
42 mDataOwner(new DataOwner(aMemoryBuffer, aLength)) {
43 MOZ_ASSERT(mDataOwner && mDataOwner->mData, "must have data");
46 void CreateInputStream(nsIInputStream** aStream,
47 ErrorResult& aRv) const override;
49 already_AddRefed<BlobImpl> CreateSlice(uint64_t aStart, uint64_t aLength,
50 const nsAString& aContentType,
51 ErrorResult& aRv) const override;
53 bool IsMemoryFile() const override { return true; }
55 size_t GetAllocationSize() const override { return mLength; }
57 size_t GetAllocationSize(
58 FallibleTArray<BlobImpl*>& aVisitedBlobImpls) const override {
59 return GetAllocationSize();
62 void GetBlobImplType(nsAString& aBlobImplType) const override {
63 aBlobImplType = u"MemoryBlobImpl"_ns;
66 class DataOwner final : public mozilla::LinkedListElement<DataOwner> {
67 public:
68 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataOwner)
69 DataOwner(void* aMemoryBuffer, uint64_t aLength)
70 : mData(aMemoryBuffer), mLength(aLength) {
71 mozilla::StaticMutexAutoLock lock(sDataOwnerMutex);
73 if (!sDataOwners) {
74 sDataOwners = new mozilla::LinkedList<DataOwner>();
75 EnsureMemoryReporterRegistered();
77 sDataOwners->insertBack(this);
80 private:
81 // Private destructor, to discourage deletion outside of Release():
82 ~DataOwner() {
83 mozilla::StaticMutexAutoLock lock(sDataOwnerMutex);
85 remove();
86 if (sDataOwners->isEmpty()) {
87 // Free the linked list if it's empty.
88 sDataOwners = nullptr;
91 free(mData);
94 public:
95 static void EnsureMemoryReporterRegistered();
97 // sDataOwners and sMemoryReporterRegistered may only be accessed while
98 // holding sDataOwnerMutex! You also must hold the mutex while touching
99 // elements of the linked list that DataOwner inherits from.
100 static mozilla::StaticMutex sDataOwnerMutex MOZ_UNANNOTATED;
101 static mozilla::StaticAutoPtr<mozilla::LinkedList<DataOwner> > sDataOwners;
102 static bool sMemoryReporterRegistered;
104 void* mData;
105 uint64_t mLength;
108 class DataOwnerAdapter final : public StreamBufferSource {
109 using DataOwner = MemoryBlobImpl::DataOwner;
111 public:
112 static nsresult Create(DataOwner* aDataOwner, size_t aStart, size_t aLength,
113 nsIInputStream** _retval);
115 Span<const char> Data() override { return mData; }
117 // This StreamBufferSource is owning, as the `mData` span references the
118 // immutable data buffer owned by `mDataOwner` which is being kept alive.
119 bool Owning() override { return true; }
121 // The memory usage from `DataOwner` is reported elsewhere, so we don't need
122 // to record it here.
123 size_t SizeOfExcludingThisEvenIfShared(MallocSizeOf) override { return 0; }
125 private:
126 ~DataOwnerAdapter() override = default;
128 DataOwnerAdapter(DataOwner* aDataOwner, Span<const char> aData)
129 : mDataOwner(aDataOwner), mData(aData) {}
131 RefPtr<DataOwner> mDataOwner;
132 Span<const char> mData;
135 private:
136 // File constructor.
137 MemoryBlobImpl(void* aMemoryBuffer, uint64_t aLength, const nsAString& aName,
138 const nsAString& aContentType, int64_t aLastModifiedDate)
139 : BaseBlobImpl(aName, aContentType, aLength, aLastModifiedDate),
140 mDataOwner(new DataOwner(aMemoryBuffer, aLength)) {
141 MOZ_ASSERT(mDataOwner && mDataOwner->mData, "must have data");
144 // Create slice
145 MemoryBlobImpl(const MemoryBlobImpl* aOther, uint64_t aStart,
146 uint64_t aLength, const nsAString& aContentType)
147 : BaseBlobImpl(aContentType, aOther->mStart + aStart, aLength),
148 mDataOwner(aOther->mDataOwner) {
149 MOZ_ASSERT(mDataOwner && mDataOwner->mData, "must have data");
152 ~MemoryBlobImpl() override = default;
154 // Used when backed by a memory store
155 RefPtr<DataOwner> mDataOwner;
158 } // namespace mozilla::dom
160 #endif // mozilla_dom_MemoryBlobImpl_h