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"
17 #include "FlippedOnce.h"
19 namespace mozilla::dom::indexedDB
{
21 class FileInfoManagerBase
{
23 bool Invalidated() const { return mInvalidated
; }
26 bool AssertValid() const {
27 if (NS_WARN_IF(Invalidated())) {
35 void Invalidate() { mInvalidated
.Flip(); }
38 FlippedOnce
<false> mInvalidated
;
41 template <typename FileManager
>
42 class FileInfoManager
: public FileInfoManagerBase
{
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
]() MOZ_REQUIRES(Mutex()) {
50 return mFileInfos
.MaybeGet(aId
);
54 bool ContainsFileInfo(int64_t aFileId
) {
55 AutoLockType
lock(Mutex());
56 return mFileInfos
.Contains(aFileId
);
59 [[nodiscard
]] SafeRefPtr
<FileInfoType
> CreateFileInfo(
60 const Maybe
<int64_t>& aMaybeId
= Nothing(),
61 const nsrefcnt aDBRefCnt
= 0) {
62 return AcquireFileInfo([this, &aMaybeId
,
63 &aDBRefCnt
]() MOZ_REQUIRES(Mutex()) {
64 const int64_t id
= aMaybeId
.isSome() ? *aMaybeId
: ++mLastFileId
;
67 MakeNotNull
<FileInfoType
*>(FileInfoManagerGuard
{},
68 SafeRefPtr
{static_cast<FileManager
*>(this),
69 AcquireStrongRefFromRawPtr
{}},
72 mFileInfos
.InsertOrUpdate(id
, fileInfo
);
74 if (aMaybeId
.isSome()) {
75 mLastFileId
= std::max(id
, mLastFileId
);
78 return Some(fileInfo
);
82 void RemoveFileInfo(const int64_t aId
, const AutoLockType
& aFileMutexLock
)
83 MOZ_REQUIRES(Mutex()) {
85 aFileMutexLock
.AssertOwns(Mutex());
87 mFileInfos
.Remove(aId
);
90 // After calling this method, callers should not call any more methods on this
92 virtual nsresult
Invalidate() {
93 AutoLockType
lock(Mutex());
95 FileInfoManagerBase::Invalidate();
97 mFileInfos
.RemoveIf([](const auto& iter
) {
98 FileInfoType
* info
= iter
.Data();
101 return !info
->LockedClearDBRefs(FileInfoManagerGuard
{});
107 struct FileInfoManagerGuard
{
108 FileInfoManagerGuard() = default;
111 static MutexType
& Mutex() { return FileManager::MutexInstance(); }
114 // Runs the given aFileInfoTableOp operation, which must return a FileInfo*,
115 // under the FileManager lock, acquires a strong reference to the returned
116 // object under the lock, and returns the strong reference.
117 template <typename FileInfoTableOp
>
118 [[nodiscard
]] SafeRefPtr
<FileInfoType
> AcquireFileInfo(
119 const FileInfoTableOp
& aFileInfoTableOp
) const {
120 if (!AssertValid()) {
121 // In release, the assertions are disabled.
125 // We cannot simply change this to SafeRefPtr<FileInfo>, because
126 // FileInfo::AddRef also acquires the FileManager::Mutex.
127 auto fileInfo
= [&aFileInfoTableOp
]() -> RefPtr
<FileInfoType
> {
128 AutoLockType
lock(Mutex());
130 const auto maybeFileInfo
= aFileInfoTableOp();
132 const auto& fileInfo
= maybeFileInfo
.ref();
133 fileInfo
->LockedAddRef();
134 return dont_AddRef(fileInfo
.get());
140 return SafeRefPtr
{std::move(fileInfo
)};
143 // Access to the following private fields must be protected by
144 // FileManager::Mutex() which is now enforced by MOZ_GUARDED_BY annotations.
145 nsTHashMap
<nsUint64HashKey
, NotNull
<FileInfoType
*>> mFileInfos
146 MOZ_GUARDED_BY(Mutex());
148 int64_t mLastFileId
MOZ_GUARDED_BY(Mutex()) = 0;
152 ~FileInfoManager() { MOZ_ASSERT(mFileInfos
.IsEmpty()); }
154 ~FileInfoManager() = default;
158 } // namespace mozilla::dom::indexedDB
160 #endif // DOM_INDEXEDDB_FILEINFOMANAGER_H_