Bug 1617170 - Make FileInfo more testable by removing the dependency on FileManager. r=dom-workers-and-storage-reviewers,janv
Also removes the dependency of FileManager(Base)/FileInfo on IndexedDatabaseManager, based on contributions by janv@mozilla.com Differential Revision: https://phabricator.services.mozilla.com/D64347
This commit is contained in:
@@ -10,7 +10,6 @@
|
||||
#include <numeric>
|
||||
#include <stdint.h> // UINTPTR_MAX, uintptr_t
|
||||
#include <utility>
|
||||
#include "FileInfo.h"
|
||||
#include "FileManager.h"
|
||||
#include "IDBCursorType.h"
|
||||
#include "IDBObjectStore.h"
|
||||
@@ -16456,6 +16455,8 @@ mozilla::ipc::IPCResult Cursor<CursorType>::RecvContinue(
|
||||
* FileManager
|
||||
******************************************************************************/
|
||||
|
||||
FileManager::MutexType FileManager::sMutex;
|
||||
|
||||
FileManager::FileManager(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup, const nsACString& aOrigin,
|
||||
const nsAString& aDatabaseName, bool aEnforcingQuota)
|
||||
@@ -16566,7 +16567,8 @@ nsresult FileManager::Init(nsIFile* aDirectory,
|
||||
// 0, but the dbRefCnt is non-zero, which will keep the FileInfo object
|
||||
// alive.
|
||||
MOZ_ASSERT(dbRefCnt > 0);
|
||||
mFileInfos.Put(id, new FileInfo(this, id, static_cast<nsrefcnt>(dbRefCnt)));
|
||||
mFileInfos.Put(id, new FileInfo(FileManagerGuard{}, this, id,
|
||||
static_cast<nsrefcnt>(dbRefCnt)));
|
||||
|
||||
mLastFileId = std::max(id, mLastFileId);
|
||||
}
|
||||
|
||||
@@ -4,141 +4,14 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "FileInfo.h"
|
||||
|
||||
#include "ActorsParent.h"
|
||||
#include "FileInfoTImpl.h"
|
||||
#include "FileManager.h"
|
||||
#include "IndexedDatabaseManager.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "nsError.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace mozilla::dom::quota;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
void FileInfo::GetReferences(int32_t* aRefCnt, int32_t* aDBRefCnt,
|
||||
int32_t* aSliceRefCnt) {
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsClosed());
|
||||
|
||||
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
|
||||
|
||||
if (aRefCnt) {
|
||||
*aRefCnt = mRefCnt;
|
||||
}
|
||||
|
||||
if (aDBRefCnt) {
|
||||
*aDBRefCnt = mDBRefCnt;
|
||||
}
|
||||
|
||||
if (aSliceRefCnt) {
|
||||
*aSliceRefCnt = mSliceRefCnt;
|
||||
}
|
||||
}
|
||||
|
||||
void FileInfo::UpdateReferences(ThreadSafeAutoRefCnt& aRefCount, int32_t aDelta,
|
||||
bool aSyncDeleteFile) {
|
||||
// XXX This can go away once DOM objects no longer hold FileInfo objects...
|
||||
// Looking at you, BlobImplBase...
|
||||
// BlobImplBase is being addressed in bug 1068975.
|
||||
if (IndexedDatabaseManager::IsClosed()) {
|
||||
MOZ_ASSERT(&aRefCount == &mRefCnt);
|
||||
MOZ_ASSERT(aDelta == 1 || aDelta == -1);
|
||||
|
||||
if (aDelta > 0) {
|
||||
++aRefCount;
|
||||
} else {
|
||||
nsrefcnt count = --aRefCount;
|
||||
if (!count) {
|
||||
mRefCnt = 1;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsClosed());
|
||||
|
||||
bool needsCleanup;
|
||||
{
|
||||
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
|
||||
|
||||
aRefCount = aRefCount + aDelta;
|
||||
|
||||
if (mRefCnt + mDBRefCnt + mSliceRefCnt > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
mFileManager->RemoveFileInfo(Id(), lock);
|
||||
|
||||
needsCleanup = !mFileManager->Invalidated();
|
||||
}
|
||||
|
||||
if (needsCleanup) {
|
||||
if (aSyncDeleteFile) {
|
||||
nsresult rv = mFileManager->SyncDeleteFile(Id());
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("FileManager cleanup failed!");
|
||||
}
|
||||
} else {
|
||||
Cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool FileInfo::LockedClearDBRefs() {
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsClosed());
|
||||
|
||||
IndexedDatabaseManager::FileMutex().AssertCurrentThreadOwns();
|
||||
|
||||
mDBRefCnt = 0;
|
||||
|
||||
if (mRefCnt || mSliceRefCnt) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// In this case, we are not responsible for removing the file info from the
|
||||
// hashtable. It's up to FileManager which is the only caller of this method.
|
||||
|
||||
MOZ_ASSERT(mFileManager->Invalidated());
|
||||
|
||||
delete this;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileInfo::Cleanup() {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
int64_t id = Id();
|
||||
|
||||
if (NS_FAILED(mFileManager->AsyncDeleteFile(id))) {
|
||||
NS_WARNING("Failed to delete file asynchronously!");
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> FileInfo::GetFileForFileInfo() const {
|
||||
const nsCOMPtr<nsIFile> directory = Manager()->GetDirectory();
|
||||
if (NS_WARN_IF(!directory)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> file = FileManager::GetFileForId(directory, Id());
|
||||
if (NS_WARN_IF(!file)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
template class FileInfoT<FileManager>;
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_fileinfo_h__
|
||||
#define mozilla_dom_indexeddb_fileinfo_h__
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
class FileManager;
|
||||
|
||||
class FileInfo final {
|
||||
template <typename FileManager, typename IndexedDatabaseManager>
|
||||
friend class FileManagerBase;
|
||||
|
||||
const int64_t mFileId;
|
||||
|
||||
ThreadSafeAutoRefCnt mRefCnt;
|
||||
ThreadSafeAutoRefCnt mDBRefCnt;
|
||||
ThreadSafeAutoRefCnt mSliceRefCnt;
|
||||
|
||||
const RefPtr<FileManager> mFileManager;
|
||||
|
||||
public:
|
||||
FileInfo(RefPtr<FileManager> aFileManager, const int64_t aFileId,
|
||||
const nsrefcnt aInitialDBRefCnt = 0)
|
||||
: mFileId(aFileId),
|
||||
mDBRefCnt(aInitialDBRefCnt),
|
||||
mFileManager(std::move(aFileManager)) {
|
||||
MOZ_ASSERT(mFileManager);
|
||||
MOZ_ASSERT(mFileId > 0);
|
||||
}
|
||||
|
||||
void AddRef() { UpdateReferences(mRefCnt, 1); }
|
||||
|
||||
void Release(const bool aSyncDeleteFile = false) {
|
||||
UpdateReferences(mRefCnt, -1, aSyncDeleteFile);
|
||||
}
|
||||
|
||||
void UpdateDBRefs(int32_t aDelta) { UpdateReferences(mDBRefCnt, aDelta); }
|
||||
|
||||
void UpdateSliceRefs(int32_t aDelta) {
|
||||
UpdateReferences(mSliceRefCnt, aDelta);
|
||||
}
|
||||
|
||||
void GetReferences(int32_t* aRefCnt, int32_t* aDBRefCnt,
|
||||
int32_t* aSliceRefCnt);
|
||||
|
||||
FileManager* Manager() const { return mFileManager; }
|
||||
|
||||
int64_t Id() const { return mFileId; }
|
||||
|
||||
nsCOMPtr<nsIFile> GetFileForFileInfo() const;
|
||||
|
||||
private:
|
||||
void UpdateReferences(ThreadSafeAutoRefCnt& aRefCount, int32_t aDelta,
|
||||
bool aSyncDeleteFile = false);
|
||||
|
||||
bool LockedClearDBRefs();
|
||||
|
||||
void Cleanup();
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_fileinfo_h__
|
||||
20
dom/indexedDB/FileInfoFwd.h
Normal file
20
dom/indexedDB/FileInfoFwd.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_fileinfofwd_h__
|
||||
#define mozilla_dom_indexeddb_fileinfofwd_h__
|
||||
|
||||
namespace mozilla::dom::indexedDB {
|
||||
|
||||
class FileManager;
|
||||
template <typename FileManager>
|
||||
class FileInfoT;
|
||||
|
||||
using FileInfo = FileInfoT<indexedDB::FileManager>;
|
||||
|
||||
} // namespace mozilla::dom::indexedDB
|
||||
|
||||
#endif // mozilla_dom_indexeddb_fileinfofwd_h__
|
||||
62
dom/indexedDB/FileInfoT.h
Normal file
62
dom/indexedDB/FileInfoT.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_fileinfot_h__
|
||||
#define mozilla_dom_indexeddb_fileinfot_h__
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
template <typename FileManager>
|
||||
class FileInfoT final {
|
||||
public:
|
||||
using AutoLock = typename FileManager::AutoLock;
|
||||
|
||||
FileInfoT(const typename FileManager::FileManagerGuard& aGuard,
|
||||
RefPtr<FileManager> aFileManager, const int64_t aFileId,
|
||||
const nsrefcnt aInitialDBRefCnt = 0);
|
||||
|
||||
void AddRef();
|
||||
void Release(const bool aSyncDeleteFile = false);
|
||||
|
||||
void UpdateDBRefs(int32_t aDelta);
|
||||
void UpdateSliceRefs(int32_t aDelta);
|
||||
|
||||
void GetReferences(int32_t* aRefCnt, int32_t* aDBRefCnt,
|
||||
int32_t* aSliceRefCnt);
|
||||
|
||||
FileManager* Manager() const;
|
||||
|
||||
int64_t Id() const;
|
||||
|
||||
nsCOMPtr<nsIFile> GetFileForFileInfo() const;
|
||||
|
||||
bool LockedClearDBRefs(const typename FileManager::FileManagerGuard& aGuard);
|
||||
|
||||
private:
|
||||
void UpdateReferences(ThreadSafeAutoRefCnt& aRefCount, int32_t aDelta,
|
||||
bool aSyncDeleteFile = false);
|
||||
|
||||
void Cleanup();
|
||||
|
||||
const int64_t mFileId;
|
||||
|
||||
ThreadSafeAutoRefCnt mRefCnt;
|
||||
ThreadSafeAutoRefCnt mDBRefCnt;
|
||||
ThreadSafeAutoRefCnt mSliceRefCnt;
|
||||
|
||||
const RefPtr<FileManager> mFileManager;
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_fileinfot_h__
|
||||
162
dom/indexedDB/FileInfoTImpl.h
Normal file
162
dom/indexedDB/FileInfoTImpl.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_fileinfotimpl_h__
|
||||
#define mozilla_dom_indexeddb_fileinfotimpl_h__
|
||||
|
||||
#include "FileInfoT.h"
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
template <typename FileManager>
|
||||
FileInfoT<FileManager>::FileInfoT(
|
||||
const typename FileManager::FileManagerGuard& aGuard,
|
||||
RefPtr<FileManager> aFileManager, const int64_t aFileId,
|
||||
const nsrefcnt aInitialDBRefCnt)
|
||||
: mFileId(aFileId),
|
||||
mDBRefCnt(aInitialDBRefCnt),
|
||||
mFileManager(std::move(aFileManager)) {
|
||||
MOZ_ASSERT(mFileId > 0);
|
||||
MOZ_ASSERT(mFileManager);
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
void FileInfoT<FileManager>::AddRef() {
|
||||
UpdateReferences(mRefCnt, 1);
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
void FileInfoT<FileManager>::Release(const bool aSyncDeleteFile) {
|
||||
UpdateReferences(mRefCnt, -1, aSyncDeleteFile);
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
void FileInfoT<FileManager>::UpdateDBRefs(int32_t aDelta) {
|
||||
UpdateReferences(mDBRefCnt, aDelta);
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
void FileInfoT<FileManager>::UpdateSliceRefs(int32_t aDelta) {
|
||||
UpdateReferences(mSliceRefCnt, aDelta);
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
void FileInfoT<FileManager>::GetReferences(int32_t* const aRefCnt,
|
||||
int32_t* const aDBRefCnt,
|
||||
int32_t* const aSliceRefCnt) {
|
||||
AutoLock lock(FileManager::Mutex());
|
||||
|
||||
if (aRefCnt) {
|
||||
*aRefCnt = mRefCnt;
|
||||
}
|
||||
|
||||
if (aDBRefCnt) {
|
||||
*aDBRefCnt = mDBRefCnt;
|
||||
}
|
||||
|
||||
if (aSliceRefCnt) {
|
||||
*aSliceRefCnt = mSliceRefCnt;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
FileManager* FileInfoT<FileManager>::Manager() const {
|
||||
return mFileManager;
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
int64_t FileInfoT<FileManager>::Id() const {
|
||||
return mFileId;
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
void FileInfoT<FileManager>::UpdateReferences(ThreadSafeAutoRefCnt& aRefCount,
|
||||
const int32_t aDelta,
|
||||
const bool aSyncDeleteFile) {
|
||||
bool needsCleanup;
|
||||
{
|
||||
AutoLock lock(FileManager::Mutex());
|
||||
|
||||
aRefCount = aRefCount + aDelta;
|
||||
|
||||
if (mRefCnt + mDBRefCnt + mSliceRefCnt > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
mFileManager->RemoveFileInfo(Id(), lock);
|
||||
|
||||
needsCleanup = !mFileManager->Invalidated();
|
||||
}
|
||||
|
||||
if (needsCleanup) {
|
||||
if (aSyncDeleteFile) {
|
||||
nsresult rv = mFileManager->SyncDeleteFile(Id());
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("FileManager cleanup failed!");
|
||||
}
|
||||
} else {
|
||||
Cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
bool FileInfoT<FileManager>::LockedClearDBRefs(
|
||||
const typename FileManager::FileManagerGuard&) {
|
||||
FileManager::Mutex().AssertCurrentThreadOwns();
|
||||
|
||||
mDBRefCnt = 0;
|
||||
|
||||
if (mRefCnt || mSliceRefCnt) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// In this case, we are not responsible for removing the file info from the
|
||||
// hashtable. It's up to FileManager which is the only caller of this method.
|
||||
|
||||
MOZ_ASSERT(mFileManager->Invalidated());
|
||||
|
||||
delete this;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
void FileInfoT<FileManager>::Cleanup() {
|
||||
int64_t id = Id();
|
||||
|
||||
if (NS_FAILED(mFileManager->AsyncDeleteFile(id))) {
|
||||
NS_WARNING("Failed to delete file asynchronously!");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FileManager>
|
||||
nsCOMPtr<nsIFile> FileInfoT<FileManager>::GetFileForFileInfo() const {
|
||||
const nsCOMPtr<nsIFile> directory = Manager()->GetDirectory();
|
||||
if (NS_WARN_IF(!directory)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> file = FileManager::GetFileForId(directory, Id());
|
||||
if (NS_WARN_IF(!file)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_fileinfotimpl_h__
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "mozilla/dom/quota/PersistenceType.h"
|
||||
#include "FileManagerBase.h"
|
||||
#include "IndexedDatabaseManager.h"
|
||||
#include "InitializedOnce.h"
|
||||
|
||||
class nsIFile;
|
||||
@@ -20,9 +19,9 @@ namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
// Implemented in ActorsParent.cpp.
|
||||
class FileManager final
|
||||
: public FileManagerBase<FileManager, dom::IndexedDatabaseManager> {
|
||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||
class FileManager final : public FileManagerBase<FileManager> {
|
||||
using PersistenceType = mozilla::dom::quota::PersistenceType;
|
||||
using FileManagerBase<FileManager>::MutexType;
|
||||
|
||||
const PersistenceType mPersistenceType;
|
||||
const nsCString mGroup;
|
||||
@@ -34,6 +33,11 @@ class FileManager final
|
||||
|
||||
const bool mEnforcingQuota;
|
||||
|
||||
// Lock protecting FileManager.mFileInfos.
|
||||
// It's s also used to atomically update FileInfo.mRefCnt and
|
||||
// FileInfo.mDBRefCnt
|
||||
static MutexType sMutex;
|
||||
|
||||
public:
|
||||
static MOZ_MUST_USE nsCOMPtr<nsIFile> GetFileForId(nsIFile* aDirectory,
|
||||
int64_t aId);
|
||||
@@ -79,6 +83,8 @@ class FileManager final
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileManager)
|
||||
|
||||
static StaticMutex& Mutex() { return sMutex; }
|
||||
|
||||
private:
|
||||
~FileManager() = default;
|
||||
};
|
||||
|
||||
@@ -9,36 +9,31 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "FileInfoT.h"
|
||||
#include "FlippedOnce.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
class FileInfo;
|
||||
|
||||
template <typename FileManager, typename IndexedDatabaseManager>
|
||||
template <typename FileManager>
|
||||
class FileManagerBase {
|
||||
public:
|
||||
using FileInfo = indexedDB::FileInfo;
|
||||
using MutexType = decltype(IndexedDatabaseManager::FileMutex());
|
||||
using AutoLock = mozilla::detail::BaseAutoLock<MutexType>;
|
||||
using FileInfo = FileInfoT<FileManager>;
|
||||
using MutexType = StaticMutex;
|
||||
using AutoLock = mozilla::detail::BaseAutoLock<MutexType&>;
|
||||
|
||||
MOZ_MUST_USE RefPtr<FileInfo> GetFileInfo(int64_t aId) const {
|
||||
if (IndexedDatabaseManager::IsClosed()) {
|
||||
MOZ_ASSERT(false, "Shouldn't be called after shutdown!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO: We cannot simply change this to RefPtr<FileInfo>, because
|
||||
// FileInfo::AddRef also acquires the IndexedDatabaseManager::FileMutex.
|
||||
// FileInfo::AddRef also acquires the FileManager::Mutex.
|
||||
// This looks quirky at least.
|
||||
FileInfo* fileInfo;
|
||||
{
|
||||
AutoLock lock(IndexedDatabaseManager::FileMutex());
|
||||
AutoLock lock(FileManager::Mutex());
|
||||
fileInfo = mFileInfos.Get(aId);
|
||||
}
|
||||
|
||||
@@ -46,18 +41,17 @@ class FileManagerBase {
|
||||
}
|
||||
|
||||
MOZ_MUST_USE RefPtr<FileInfo> CreateFileInfo() {
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsClosed());
|
||||
|
||||
// TODO: We cannot simply change this to RefPtr<FileInfo>, because
|
||||
// FileInfo::AddRef also acquires the IndexedDatabaseManager::FileMutex.
|
||||
// FileInfo::AddRef also acquires the FileManager::Mutex.
|
||||
// This looks quirky at least.
|
||||
FileInfo* fileInfo;
|
||||
{
|
||||
AutoLock lock(IndexedDatabaseManager::FileMutex());
|
||||
AutoLock lock(FileManager::Mutex());
|
||||
|
||||
const int64_t id = ++mLastFileId;
|
||||
|
||||
fileInfo = new FileInfo(static_cast<FileManager*>(this), id);
|
||||
fileInfo =
|
||||
new FileInfo(FileManagerGuard{}, static_cast<FileManager*>(this), id);
|
||||
|
||||
mFileInfos.Put(id, fileInfo);
|
||||
}
|
||||
@@ -65,20 +59,15 @@ class FileManagerBase {
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
void RemoveFileInfo(const int64_t aId, const AutoLock& aFilesMutexLock) {
|
||||
void RemoveFileInfo(const int64_t aId, const AutoLock& aFileMutexLock) {
|
||||
#ifdef DEBUG
|
||||
aFilesMutexLock.AssertOwns(IndexedDatabaseManager::FileMutex());
|
||||
aFileMutexLock.AssertOwns(FileManager::Mutex());
|
||||
#endif
|
||||
mFileInfos.Remove(aId);
|
||||
}
|
||||
|
||||
nsresult Invalidate() {
|
||||
if (IndexedDatabaseManager::IsClosed()) {
|
||||
MOZ_ASSERT(false, "Shouldn't be called after shutdown!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
AutoLock lock(IndexedDatabaseManager::FileMutex());
|
||||
AutoLock lock(FileManager::Mutex());
|
||||
|
||||
mInvalidated.Flip();
|
||||
|
||||
@@ -86,7 +75,7 @@ class FileManagerBase {
|
||||
FileInfo* info = iter.Data();
|
||||
MOZ_ASSERT(info);
|
||||
|
||||
return !info->LockedClearDBRefs();
|
||||
return !info->LockedClearDBRefs(FileManagerGuard{});
|
||||
});
|
||||
|
||||
return NS_OK;
|
||||
@@ -102,7 +91,7 @@ class FileManagerBase {
|
||||
~FileManagerBase() = default;
|
||||
|
||||
// Access to the following fields must be protected by
|
||||
// IndexedDatabaseManager::FileMutex()
|
||||
// FileManager::Mutex()
|
||||
int64_t mLastFileId = 0;
|
||||
nsDataHashtable<nsUint64HashKey, FileInfo*> mFileInfos;
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "IDBDatabase.h"
|
||||
|
||||
#include "FileInfo.h"
|
||||
#include "IDBEvents.h"
|
||||
#include "IDBFactory.h"
|
||||
#include "IDBIndex.h"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "IDBIndex.h"
|
||||
|
||||
#include "FileInfo.h"
|
||||
#include "IDBCursorType.h"
|
||||
#include "IDBEvents.h"
|
||||
#include "IDBKeyRange.h"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "IDBMutableFile.h"
|
||||
|
||||
#include "ActorsChild.h"
|
||||
#include "FileInfo.h"
|
||||
#include "IDBDatabase.h"
|
||||
#include "IDBFactory.h"
|
||||
#include "IDBFileHandle.h"
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <numeric>
|
||||
#include <utility>
|
||||
|
||||
#include "FileInfo.h"
|
||||
#include "IDBCursorType.h"
|
||||
#include "IDBDatabase.h"
|
||||
#include "IDBEvents.h"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "InitializedOnce.h"
|
||||
#include "FileInfoFwd.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@@ -22,7 +23,6 @@ class IDBMutableFile;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class FileInfo;
|
||||
class SerializedStructuredCloneReadInfo;
|
||||
|
||||
struct StructuredCloneFile {
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
# error Must include IndexedDatabase.h first
|
||||
#endif
|
||||
|
||||
#include "FileInfo.h"
|
||||
#include "FileManager.h"
|
||||
#include "IDBMutableFile.h"
|
||||
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
|
||||
|
||||
@@ -215,9 +215,7 @@ auto DatabaseNameMatchPredicate(const nsAString* const aName) {
|
||||
|
||||
} // namespace
|
||||
|
||||
IndexedDatabaseManager::IndexedDatabaseManager()
|
||||
: mFileMutex("IndexedDatabaseManager.mFileMutex"),
|
||||
mBackgroundActor(nullptr) {
|
||||
IndexedDatabaseManager::IndexedDatabaseManager() : mBackgroundActor(nullptr) {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
|
||||
|
||||
@@ -132,13 +132,6 @@ class IndexedDatabaseManager final {
|
||||
|
||||
static const nsCString& GetLocale();
|
||||
|
||||
static mozilla::Mutex& FileMutex() {
|
||||
IndexedDatabaseManager* mgr = Get();
|
||||
NS_ASSERTION(mgr, "Must have a manager here!");
|
||||
|
||||
return mgr->mFileMutex;
|
||||
}
|
||||
|
||||
static nsresult CommonPostHandleEvent(EventChainPostVisitor& aVisitor,
|
||||
IDBFactory* aFactory);
|
||||
|
||||
@@ -164,11 +157,6 @@ class IndexedDatabaseManager final {
|
||||
nsClassHashtable<nsRefPtrHashKey<FileManager>, nsTArray<int64_t>>
|
||||
mPendingDeleteInfos;
|
||||
|
||||
// Lock protecting FileManager.mFileInfos.
|
||||
// It's s also used to atomically update FileInfo.mRefCnt, FileInfo.mDBRefCnt
|
||||
// and FileInfo.mSliceRefCnt
|
||||
mozilla::Mutex mFileMutex;
|
||||
|
||||
nsCString mLocale;
|
||||
|
||||
indexedDB::BackgroundUtilsChild* mBackgroundActor;
|
||||
|
||||
@@ -24,6 +24,7 @@ XPCSHELL_TESTS_MANIFESTS += [
|
||||
TEST_DIRS += ['test/gtest']
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'FileInfoFwd.h',
|
||||
'FlippedOnce.h',
|
||||
'IDBCursor.h',
|
||||
'IDBCursorType.h',
|
||||
|
||||
Reference in New Issue
Block a user