Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / indexedDB / FileInfoManager.h
blob75842aa53fc6ed9e08beecd3ba45f5d463ad992e
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 DOM_INDEXEDDB_FILEINFOMANAGER_H_
8 #define DOM_INDEXEDDB_FILEINFOMANAGER_H_
10 #include "mozilla/Attributes.h"
11 #include "mozilla/Mutex.h"
12 #include "mozilla/StaticMutex.h"
13 #include "nsTHashMap.h"
14 #include "nsHashKeys.h"
15 #include "nsISupportsImpl.h"
16 #include "FileInfo.h"
17 #include "FlippedOnce.h"
19 namespace mozilla::dom::indexedDB {
21 class FileInfoManagerBase {
22 public:
23 bool Invalidated() const { return mInvalidated; }
25 protected:
26 bool AssertValid() const {
27 if (NS_WARN_IF(Invalidated())) {
28 MOZ_ASSERT(false);
29 return false;
32 return true;
35 void Invalidate() { mInvalidated.Flip(); }
37 private:
38 FlippedOnce<false> mInvalidated;
41 template <typename FileManager>
42 class FileInfoManager : public FileInfoManagerBase {
43 public:
44 using FileInfoType = FileInfo<FileManager>;
45 using MutexType = StaticMutex;
46 using AutoLockType = mozilla::detail::BaseAutoLock<MutexType&>;
48 [[nodiscard]] SafeRefPtr<FileInfoType> GetFileInfo(int64_t aId) const {
49 return AcquireFileInfo([this, aId] { return mFileInfos.MaybeGet(aId); });
52 [[nodiscard]] SafeRefPtr<FileInfoType> CreateFileInfo() {
53 return AcquireFileInfo([this] {
54 const int64_t id = ++mLastFileId;
56 auto fileInfo =
57 MakeNotNull<FileInfoType*>(FileInfoManagerGuard{},
58 SafeRefPtr{static_cast<FileManager*>(this),
59 AcquireStrongRefFromRawPtr{}},
60 id);
62 mFileInfos.InsertOrUpdate(id, fileInfo);
63 return Some(fileInfo);
64 });
67 void RemoveFileInfo(const int64_t aId, const AutoLockType& aFileMutexLock) {
68 #ifdef DEBUG
69 aFileMutexLock.AssertOwns(FileManager::Mutex());
70 #endif
71 mFileInfos.Remove(aId);
74 // After calling this method, callers should not call any more methods on this
75 // class.
76 virtual nsresult Invalidate() {
77 AutoLockType lock(FileManager::Mutex());
79 FileInfoManagerBase::Invalidate();
81 mFileInfos.RemoveIf([](const auto& iter) {
82 FileInfoType* info = iter.Data();
83 MOZ_ASSERT(info);
85 return !info->LockedClearDBRefs(FileInfoManagerGuard{});
86 });
88 return NS_OK;
91 struct FileInfoManagerGuard {
92 FileInfoManagerGuard() = default;
95 private:
96 // Runs the given aFileInfoTableOp operation, which must return a FileInfo*,
97 // under the FileManager lock, acquires a strong reference to the returned
98 // object under the lock, and returns the strong reference.
99 template <typename FileInfoTableOp>
100 [[nodiscard]] SafeRefPtr<FileInfoType> AcquireFileInfo(
101 const FileInfoTableOp& aFileInfoTableOp) const {
102 if (!AssertValid()) {
103 // In release, the assertions are disabled.
104 return nullptr;
107 // We cannot simply change this to SafeRefPtr<FileInfo>, because
108 // FileInfo::AddRef also acquires the FileManager::Mutex.
109 auto fileInfo = [&aFileInfoTableOp]() -> RefPtr<FileInfoType> {
110 AutoLockType lock(FileManager::Mutex());
112 const auto maybeFileInfo = aFileInfoTableOp();
113 if (maybeFileInfo) {
114 const auto& fileInfo = maybeFileInfo.ref();
115 fileInfo->LockedAddRef();
116 return dont_AddRef(fileInfo.get());
119 return {};
120 }();
122 return SafeRefPtr{std::move(fileInfo)};
125 protected:
126 #ifdef DEBUG
127 ~FileInfoManager() { MOZ_ASSERT(mFileInfos.IsEmpty()); }
128 #else
129 ~FileInfoManager() = default;
130 #endif
132 // Access to the following fields must be protected by
133 // FileManager::Mutex()
134 int64_t mLastFileId = 0;
135 nsTHashMap<nsUint64HashKey, NotNull<FileInfoType*>> mFileInfos;
138 } // namespace mozilla::dom::indexedDB
140 #endif // DOM_INDEXEDDB_FILEINFOMANAGER_H_