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
] { return mFileInfos
.MaybeGet(aId
); });
52 [[nodiscard
]] SafeRefPtr
<FileInfoType
> CreateFileInfo() {
53 return AcquireFileInfo([this] {
54 const int64_t id
= ++mLastFileId
;
57 MakeNotNull
<FileInfoType
*>(FileInfoManagerGuard
{},
58 SafeRefPtr
{static_cast<FileManager
*>(this),
59 AcquireStrongRefFromRawPtr
{}},
62 mFileInfos
.InsertOrUpdate(id
, fileInfo
);
63 return Some(fileInfo
);
67 void RemoveFileInfo(const int64_t aId
, const AutoLockType
& aFileMutexLock
) {
69 aFileMutexLock
.AssertOwns(FileManager::Mutex());
71 mFileInfos
.Remove(aId
);
74 // After calling this method, callers should not call any more methods on this
76 virtual nsresult
Invalidate() {
77 AutoLockType
lock(FileManager::Mutex());
79 FileInfoManagerBase::Invalidate();
81 mFileInfos
.RemoveIf([](const auto& iter
) {
82 FileInfoType
* info
= iter
.Data();
85 return !info
->LockedClearDBRefs(FileInfoManagerGuard
{});
91 struct FileInfoManagerGuard
{
92 FileInfoManagerGuard() = default;
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.
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();
114 const auto& fileInfo
= maybeFileInfo
.ref();
115 fileInfo
->LockedAddRef();
116 return dont_AddRef(fileInfo
.get());
122 return SafeRefPtr
{std::move(fileInfo
)};
127 ~FileInfoManager() { MOZ_ASSERT(mFileInfos
.IsEmpty()); }
129 ~FileInfoManager() = default;
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_