Backed out 10 changesets (bug 1623278, bug 1617170, bug 1620273, bug 1597954) for causing bustages.

CLOSED TREE

Backed out changeset 50c0e58dd654 (bug 1623278)
Backed out changeset b31ddbcdd2f2 (bug 1597954)
Backed out changeset 8b03993a9234 (bug 1623278)
Backed out changeset ad7b08acadd6 (bug 1623278)
Backed out changeset bb094a6084b3 (bug 1623278)
Backed out changeset 7fdf38a403bb (bug 1623278)
Backed out changeset d69cf5fcb571 (bug 1620273)
Backed out changeset 5abef9862e60 (bug 1617170)
Backed out changeset 11d9ccb4ddd8 (bug 1617170)
Backed out changeset 6df7028b41d0 (bug 1617170)
This commit is contained in:
Mihai Alexandru Michis 2020-03-19 13:30:26 +02:00
parent 01263f8b95
commit 2922453b6e
21 changed files with 971 additions and 1189 deletions

View File

@ -519,17 +519,16 @@ auto DeserializeStructuredCloneFiles(
MOZ_ASSERT_IF(aForPreprocess, aSerializedFiles.Length() == 1);
const auto count = aSerializedFiles.Length();
auto files = nsTArray<StructuredCloneFileChild>(count);
auto files = nsTArray<StructuredCloneFile>(count);
for (const auto& serializedFile : aSerializedFiles) {
MOZ_ASSERT_IF(
aForPreprocess,
serializedFile.type() == StructuredCloneFileBase::eStructuredClone);
MOZ_ASSERT_IF(aForPreprocess, serializedFile.type() ==
StructuredCloneFile::eStructuredClone);
const BlobOrMutableFile& blobOrMutableFile = serializedFile.file();
switch (serializedFile.type()) {
case StructuredCloneFileBase::eBlob: {
case StructuredCloneFile::eBlob: {
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::TIPCBlob);
const IPCBlob& ipcBlob = blobOrMutableFile.get_IPCBlob();
@ -540,19 +539,19 @@ auto DeserializeStructuredCloneFiles(
RefPtr<Blob> blob = Blob::Create(aDatabase->GetOwnerGlobal(), blobImpl);
MOZ_ASSERT(blob);
files.EmplaceBack(StructuredCloneFileBase::eBlob, std::move(blob));
files.EmplaceBack(StructuredCloneFile::eBlob, std::move(blob));
break;
}
case StructuredCloneFileBase::eMutableFile: {
case StructuredCloneFile::eMutableFile: {
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t ||
blobOrMutableFile.type() ==
BlobOrMutableFile::TPBackgroundMutableFileChild);
switch (blobOrMutableFile.type()) {
case BlobOrMutableFile::Tnull_t: {
files.EmplaceBack(StructuredCloneFileBase::eMutableFile);
files.EmplaceBack(StructuredCloneFile::eMutableFile);
break;
}
@ -582,7 +581,7 @@ auto DeserializeStructuredCloneFiles(
break;
}
case StructuredCloneFileBase::eStructuredClone: {
case StructuredCloneFile::eStructuredClone: {
if (aForPreprocess) {
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::TIPCBlob);
@ -595,19 +594,19 @@ auto DeserializeStructuredCloneFiles(
Blob::Create(aDatabase->GetOwnerGlobal(), blobImpl);
MOZ_ASSERT(blob);
files.EmplaceBack(StructuredCloneFileBase::eStructuredClone,
files.EmplaceBack(StructuredCloneFile::eStructuredClone,
std::move(blob));
} else {
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t);
files.EmplaceBack(StructuredCloneFileBase::eStructuredClone);
files.EmplaceBack(StructuredCloneFile::eStructuredClone);
}
break;
}
case StructuredCloneFileBase::eWasmBytecode:
case StructuredCloneFileBase::eWasmCompiled: {
case StructuredCloneFile::eWasmBytecode:
case StructuredCloneFile::eWasmCompiled: {
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t);
files.EmplaceBack(serializedFile.type());
@ -1368,7 +1367,7 @@ class BackgroundRequestChild::PreprocessHelper final
mActor = nullptr;
}
nsresult Init(const StructuredCloneFileChild& aFile);
nsresult Init(const StructuredCloneFile& aFile);
nsresult Dispatch();
@ -2942,10 +2941,10 @@ mozilla::ipc::IPCResult BackgroundRequestChild::RecvPreprocess(
}
nsresult BackgroundRequestChild::PreprocessHelper::Init(
const StructuredCloneFileChild& aFile) {
const StructuredCloneFile& aFile) {
AssertIsOnOwningThread();
MOZ_ASSERT(aFile.HasBlob());
MOZ_ASSERT(aFile.Type() == StructuredCloneFileBase::eStructuredClone);
MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eStructuredClone);
MOZ_ASSERT(mState == State::Initial);
// The stream transport service is used for asynchronous processing. It has a
@ -3421,12 +3420,12 @@ void BackgroundCursorChild<CursorType>::SendDeleteMeInternal() {
MOZ_ASSERT(!mStrongRequest);
MOZ_ASSERT(!mStrongCursor);
mRequest.destroy();
mRequest.reset();
mTransaction = nullptr;
// TODO: The things until here could be pulled up to
// BackgroundCursorChildBase.
mSource.destroy();
mSource.reset();
if (mCursor) {
mCursor->ClearBackgroundActor();
@ -3677,9 +3676,9 @@ void BackgroundCursorChild<CursorType>::ActorDestroy(ActorDestroyReason aWhy) {
}
#ifdef DEBUG
mRequest.maybeDestroy();
mRequest.maybeReset();
mTransaction = nullptr;
mSource.maybeDestroy();
mSource.maybeReset();
#endif
}

View File

@ -24,7 +24,6 @@
#include "mozilla/dom/PBackgroundFileHandleChild.h"
#include "mozilla/dom/PBackgroundFileRequestChild.h"
#include "mozilla/dom/PBackgroundMutableFileChild.h"
#include "mozilla/InitializedOnce.h"
#include "mozilla/UniquePtr.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
@ -637,7 +636,7 @@ class BackgroundCursorChildBase : public PBackgroundIDBCursorChild {
private:
NS_DECL_OWNINGTHREAD
protected:
InitializedOnceNotNull<IDBRequest* const> mRequest;
InitializedOnceMustBeTrue<IDBRequest* const> mRequest;
IDBTransaction* mTransaction;
// These are only set while a request is in progress.
@ -682,7 +681,7 @@ class BackgroundCursorChild final : public BackgroundCursorChildBase {
friend class BackgroundTransactionChild;
friend class BackgroundVersionChangeTransactionChild;
InitializedOnceNotNull<SourceType* const> mSource;
InitializedOnceMustBeTrue<SourceType* const> mSource;
IDBCursorImpl<CursorType>* mCursor;
std::deque<CursorData<CursorType>> mCachedResponses, mDelayedResponses;

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,6 @@
#include "nsISupportsImpl.h"
#include "nsCOMPtr.h"
#include "SafeRefPtr.h"
namespace mozilla {
namespace dom {
@ -21,7 +20,7 @@ class FileInfoT final {
using AutoLock = typename FileManager::AutoLock;
FileInfoT(const typename FileManager::FileManagerGuard& aGuard,
SafeRefPtr<FileManager> aFileManager, const int64_t aFileId,
RefPtr<FileManager> aFileManager, const int64_t aFileId,
const nsrefcnt aInitialDBRefCnt = 0);
void AddRef();
@ -31,7 +30,7 @@ class FileInfoT final {
void GetReferences(int32_t* aRefCnt, int32_t* aDBRefCnt);
FileManager& Manager() const;
FileManager* Manager() const;
int64_t Id() const;
@ -50,7 +49,7 @@ class FileInfoT final {
ThreadSafeAutoRefCnt mRefCnt;
ThreadSafeAutoRefCnt mDBRefCnt;
const SafeRefPtr<FileManager> mFileManager;
const RefPtr<FileManager> mFileManager;
};
} // namespace indexedDB

View File

@ -19,7 +19,7 @@ namespace indexedDB {
template <typename FileManager>
FileInfoT<FileManager>::FileInfoT(
const typename FileManager::FileManagerGuard& aGuard,
SafeRefPtr<FileManager> aFileManager, const int64_t aFileId,
RefPtr<FileManager> aFileManager, const int64_t aFileId,
const nsrefcnt aInitialDBRefCnt)
: mFileId(aFileId),
mDBRefCnt(aInitialDBRefCnt),
@ -58,8 +58,8 @@ void FileInfoT<FileManager>::GetReferences(int32_t* const aRefCnt,
}
template <typename FileManager>
FileManager& FileInfoT<FileManager>::Manager() const {
return *mFileManager;
FileManager* FileInfoT<FileManager>::Manager() const {
return mFileManager;
}
template <typename FileManager>
@ -136,7 +136,7 @@ void FileInfoT<FileManager>::Cleanup() {
template <typename FileManager>
nsCOMPtr<nsIFile> FileInfoT<FileManager>::GetFileForFileInfo() const {
const nsCOMPtr<nsIFile> directory = Manager().GetDirectory();
const nsCOMPtr<nsIFile> directory = Manager()->GetDirectory();
if (NS_WARN_IF(!directory)) {
return nullptr;
}

View File

@ -8,8 +8,8 @@
#define mozilla_dom_indexeddb_filemanager_h__
#include "mozilla/dom/quota/PersistenceType.h"
#include "mozilla/InitializedOnce.h"
#include "FileManagerBase.h"
#include "InitializedOnce.h"
class nsIFile;
class mozIStorageConnection;
@ -28,8 +28,8 @@ class FileManager final : public FileManagerBase<FileManager> {
const nsCString mOrigin;
const nsString mDatabaseName;
LazyInitializedOnce<const nsString> mDirectoryPath;
LazyInitializedOnce<const nsString> mJournalDirectoryPath;
InitializedOnce<const nsString, LazyInit::Allow> mDirectoryPath;
InitializedOnce<const nsString, LazyInit::Allow> mJournalDirectoryPath;
const bool mEnforcingQuota;

View File

@ -27,13 +27,13 @@ class FileManagerBase {
using MutexType = StaticMutex;
using AutoLock = mozilla::detail::BaseAutoLock<MutexType&>;
MOZ_MUST_USE SafeRefPtr<FileInfo> GetFileInfo(int64_t aId) const {
MOZ_MUST_USE RefPtr<FileInfo> GetFileInfo(int64_t aId) const {
if (!AssertValid()) {
// In release, the assertions are disabled.
return nullptr;
}
// TODO: We cannot simply change this to SafeRefPtr<FileInfo>, because
// TODO: We cannot simply change this to RefPtr<FileInfo>, because
// FileInfo::AddRef also acquires the FileManager::Mutex.
// This looks quirky at least.
FileInfo* fileInfo;
@ -42,16 +42,16 @@ class FileManagerBase {
fileInfo = mFileInfos.Get(aId);
}
return {fileInfo, AcquireStrongRefFromRawPtr{}};
return fileInfo;
}
MOZ_MUST_USE SafeRefPtr<FileInfo> CreateFileInfo() {
MOZ_MUST_USE RefPtr<FileInfo> CreateFileInfo() {
if (!AssertValid()) {
// In release, the assertions are disabled.
return nullptr;
}
// TODO: We cannot simply change this to SafeRefPtr<FileInfo>, because
// TODO: We cannot simply change this to RefPtr<FileInfo>, because
// FileInfo::AddRef also acquires the FileManager::Mutex.
// This looks quirky at least.
FileInfo* fileInfo;
@ -60,15 +60,13 @@ class FileManagerBase {
const int64_t id = ++mLastFileId;
fileInfo = new FileInfo(FileManagerGuard{},
SafeRefPtr{static_cast<FileManager*>(this),
AcquireStrongRefFromRawPtr{}},
id);
fileInfo =
new FileInfo(FileManagerGuard{}, static_cast<FileManager*>(this), id);
mFileInfos.Put(id, fileInfo);
}
return {fileInfo, AcquireStrongRefFromRawPtr{}};
return fileInfo;
}
void RemoveFileInfo(const int64_t aId, const AutoLock& aFileMutexLock) {

View File

@ -9,13 +9,13 @@
#include "IDBCursorType.h"
#include "IndexedDatabase.h"
#include "InitializedOnce.h"
#include "js/RootingAPI.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/IDBCursorBinding.h"
#include "mozilla/dom/IDBTransaction.h"
#include "mozilla/dom/indexedDB/Key.h"
#include "mozilla/dom/quota/CheckedUnsafePtr.h"
#include "mozilla/InitializedOnce.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
@ -52,7 +52,7 @@ class IDBCursor : public nsISupports, public nsWrapperCache {
using Type = IDBCursorType;
protected:
InitializedOnceNotNull<indexedDB::BackgroundCursorChildBase* const>
InitializedOnceMustBeTrue<indexedDB::BackgroundCursorChildBase* const>
mBackgroundActor;
// TODO: mRequest could be made const if Bug 1575173 is resolved. It is
@ -144,7 +144,7 @@ class IDBCursor : public nsISupports, public nsWrapperCache {
void ClearBackgroundActor() {
AssertIsOnOwningThread();
mBackgroundActor.destroy();
mBackgroundActor.reset();
}
virtual void InvalidateCachedResponses() = 0;

View File

@ -79,7 +79,7 @@ IndexUpdateInfo MakeIndexUpdateInfo(const int64_t aIndexID, const Key& aKey,
struct IDBObjectStore::StructuredCloneWriteInfo {
JSAutoStructuredCloneBuffer mCloneBuffer;
nsTArray<StructuredCloneFileChild> mFiles;
nsTArray<StructuredCloneFile> mFiles;
IDBDatabase* mDatabase;
uint64_t mOffsetToKeyProp;
@ -117,7 +117,7 @@ struct IDBObjectStore::StructuredCloneWriteInfo {
// what strong references have been acquired so that they can be freed even
// if a de-serialization does not occur.
struct IDBObjectStore::StructuredCloneInfo {
nsTArray<StructuredCloneFileChild> mFiles;
nsTArray<StructuredCloneFile> mFiles;
};
namespace {
@ -229,7 +229,7 @@ bool StructuredCloneWriteCallback(JSContext* aCx,
return false;
}
const DebugOnly<StructuredCloneFileChild*> newFile =
const DebugOnly<StructuredCloneFile*> newFile =
cloneWriteInfo->mFiles.EmplaceBack(mutableFile);
MOZ_ASSERT(newFile);
@ -293,9 +293,8 @@ bool StructuredCloneWriteCallback(JSContext* aCx,
}
}
const DebugOnly<StructuredCloneFileChild*> newFile =
cloneWriteInfo->mFiles.EmplaceBack(StructuredCloneFileBase::eBlob,
blob);
const DebugOnly<StructuredCloneFile*> newFile =
cloneWriteInfo->mFiles.EmplaceBack(StructuredCloneFile::eBlob, blob);
MOZ_ASSERT(newFile);
return true;
@ -338,8 +337,8 @@ bool CopyingStructuredCloneWriteCallback(JSContext* aCx,
return false;
}
const DebugOnly<StructuredCloneFileChild*> newFile =
cloneInfo->mFiles.EmplaceBack(StructuredCloneFileBase::eBlob, blob);
const DebugOnly<StructuredCloneFile*> newFile =
cloneInfo->mFiles.EmplaceBack(StructuredCloneFile::eBlob, blob);
MOZ_ASSERT(newFile);
return true;
@ -361,7 +360,7 @@ bool CopyingStructuredCloneWriteCallback(JSContext* aCx,
return false;
}
const DebugOnly<StructuredCloneFileChild*> newFile =
const DebugOnly<StructuredCloneFile*> newFile =
cloneInfo->mFiles.EmplaceBack(mutableFile);
MOZ_ASSERT(newFile);
@ -422,17 +421,17 @@ JSObject* CopyingStructuredCloneReadCallback(
return nullptr;
}
StructuredCloneFileChild& file = cloneInfo->mFiles[aData];
StructuredCloneFile& file = cloneInfo->mFiles[aData];
switch (static_cast<StructuredCloneTags>(aTag)) {
case SCTAG_DOM_BLOB:
MOZ_ASSERT(file.Type() == StructuredCloneFileBase::eBlob);
MOZ_ASSERT(file.Type() == StructuredCloneFile::eBlob);
MOZ_ASSERT(!file.Blob().IsFile());
return WrapAsJSObject(aCx, file.MutableBlob());
case SCTAG_DOM_FILE: {
MOZ_ASSERT(file.Type() == StructuredCloneFileBase::eBlob);
MOZ_ASSERT(file.Type() == StructuredCloneFile::eBlob);
JS::Rooted<JSObject*> result(aCx);
@ -454,7 +453,7 @@ JSObject* CopyingStructuredCloneReadCallback(
}
case SCTAG_DOM_MUTABLEFILE:
MOZ_ASSERT(file.Type() == StructuredCloneFileBase::eMutableFile);
MOZ_ASSERT(file.Type() == StructuredCloneFile::eMutableFile);
return WrapAsJSObject(aCx, file.MutableMutableFile());
@ -607,8 +606,7 @@ void IDBObjectStore::AppendIndexUpdateInfo(
}
// static
void IDBObjectStore::ClearCloneReadInfo(
StructuredCloneReadInfoChild& aReadInfo) {
void IDBObjectStore::ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo) {
// This is kind of tricky, we only want to release stuff on the main thread,
// but we can end up being called on other threads if we have already been
// cleared on the main thread.
@ -828,7 +826,7 @@ RefPtr<IDBRequest> IDBObjectStore::AddOrPut(JSContext* aCx,
commonParams.indexUpdateInfos().SwapElements(updateInfo);
// Convert any blobs or mutable files into FileAddInfo.
nsTArray<StructuredCloneFileChild>& files = cloneWriteInfo.mFiles;
nsTArray<StructuredCloneFile>& files = cloneWriteInfo.mFiles;
if (!files.IsEmpty()) {
const uint32_t count = files.Length();
@ -842,13 +840,13 @@ RefPtr<IDBRequest> IDBObjectStore::AddOrPut(JSContext* aCx,
IDBDatabase* const database = mTransaction->Database();
for (uint32_t index = 0; index < count; index++) {
StructuredCloneFileChild& file = files[index];
StructuredCloneFile& file = files[index];
FileAddInfo* const fileAddInfo = fileAddInfos.AppendElement(fallible);
MOZ_ASSERT(fileAddInfo);
switch (file.Type()) {
case StructuredCloneFileBase::eBlob: {
case StructuredCloneFile::eBlob: {
MOZ_ASSERT(file.HasBlob());
MOZ_ASSERT(!file.HasMutableFile());
@ -861,12 +859,12 @@ RefPtr<IDBRequest> IDBObjectStore::AddOrPut(JSContext* aCx,
}
fileAddInfo->file() = fileActor;
fileAddInfo->type() = StructuredCloneFileBase::eBlob;
fileAddInfo->type() = StructuredCloneFile::eBlob;
break;
}
case StructuredCloneFileBase::eMutableFile: {
case StructuredCloneFile::eMutableFile: {
MOZ_ASSERT(file.HasMutableFile());
MOZ_ASSERT(!file.HasBlob());
@ -879,13 +877,13 @@ RefPtr<IDBRequest> IDBObjectStore::AddOrPut(JSContext* aCx,
}
fileAddInfo->file() = mutableFileActor;
fileAddInfo->type() = StructuredCloneFileBase::eMutableFile;
fileAddInfo->type() = StructuredCloneFile::eMutableFile;
break;
}
case StructuredCloneFileBase::eWasmBytecode:
case StructuredCloneFileBase::eWasmCompiled: {
case StructuredCloneFile::eWasmBytecode:
case StructuredCloneFile::eWasmCompiled: {
MOZ_ASSERT(file.HasBlob());
MOZ_ASSERT(!file.HasMutableFile());

View File

@ -104,8 +104,7 @@ class IDBObjectStore final : public nsISupports, public nsWrapperCache {
nsTArray<IndexUpdateInfo>* aUpdateInfoArray,
ErrorResult* aRv);
static void ClearCloneReadInfo(
indexedDB::StructuredCloneReadInfoChild& aReadInfo);
static void ClearCloneReadInfo(indexedDB::StructuredCloneReadInfo& aReadInfo);
static bool DeserializeValue(JSContext* aCx,
StructuredCloneReadInfoChild&& aCloneReadInfo,

View File

@ -175,32 +175,42 @@ bool ReadWasmModule(JSStructuredCloneReader* aReader, WasmModuleData* aRetval) {
return true;
}
template <typename StructuredCloneFile>
class ValueDeserializationHelper;
class ValueDeserializationHelperBase {
class ValueDeserializationHelper {
public:
static bool CreateAndWrapWasmModule(JSContext* aCx,
const StructuredCloneFileBase& aFile,
const WasmModuleData& aData,
JS::MutableHandle<JSObject*> aResult) {
static bool CreateAndWrapMutableFile(JSContext* aCx,
StructuredCloneFile& aFile,
const MutableFileData& aData,
JS::MutableHandle<JSObject*> aResult) {
MOZ_ASSERT(aCx);
MOZ_ASSERT(aFile.Type() == StructuredCloneFileBase::eWasmBytecode);
// Both on the parent and child side, just create a plain object here,
// support for de-serialization of WebAssembly.Modules has been removed in
// bug 1561876. Full removal is tracked in bug 1487479.
// If we have eBlob, we are in an IDB SQLite schema upgrade where we don't
// care about a real 'MutableFile', but we just care of having a proper
// |mType| flag.
if (aFile.Type() == StructuredCloneFile::eBlob) {
aFile.MutateType(StructuredCloneFile::eMutableFile);
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
if (NS_WARN_IF(!obj)) {
// Just make a dummy object.
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
if (NS_WARN_IF(!obj)) {
return false;
}
aResult.set(obj);
return true;
}
MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eMutableFile);
if (!aFile.HasMutableFile() || !NS_IsMainThread()) {
return false;
}
aResult.set(obj);
return true;
aFile.MutableMutableFile().SetLazyData(aData.name, aData.type);
return WrapAsJSObject(aCx, aFile.MutableMutableFile(), aResult);
}
template <typename StructuredCloneFile>
static bool CreateAndWrapBlobOrFile(JSContext* aCx, IDBDatabase* aDatabase,
const StructuredCloneFile& aFile,
const BlobOrFileData& aData,
@ -209,10 +219,48 @@ class ValueDeserializationHelperBase {
MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE ||
aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
aData.tag == SCTAG_DOM_BLOB);
MOZ_ASSERT(aFile.Type() == StructuredCloneFileBase::eBlob);
MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eBlob);
const auto blob = ValueDeserializationHelper<StructuredCloneFile>::GetBlob(
aCx, aDatabase, aFile);
const auto blob = [&aFile, aDatabase, aCx]() -> RefPtr<Blob> {
if (aFile.HasBlob()) {
return aFile.BlobPtr();
}
// It can happen that this IDB is chrome code, so there is no parent, but
// still we want to set a correct parent for the new File object.
const auto global = [aDatabase, aCx]() -> nsCOMPtr<nsIGlobalObject> {
if (NS_IsMainThread()) {
if (aDatabase && aDatabase->GetParentObject()) {
return aDatabase->GetParentObject();
}
return xpc::CurrentNativeGlobal(aCx);
}
const WorkerPrivate* const workerPrivate =
GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
WorkerGlobalScope* const globalScope = workerPrivate->GlobalScope();
MOZ_ASSERT(globalScope);
return do_QueryObject(globalScope);
}();
MOZ_ASSERT(global);
/* If we are creating an index, we do not have an mBlob but do have an
* FileInfo. Unlike other index or upgrade cases, we do need a
* real-looking Blob/File instance because the index's key path can
* reference their properties. Rather than create a fake-looking object,
* create a real Blob. */
const nsCOMPtr<nsIFile> file = aFile.FileInfo().GetFileForFileInfo();
if (!file) {
return nullptr;
}
const auto impl = MakeRefPtr<FileBlobImpl>(file);
impl->SetFileId(aFile.FileInfo().Id());
return File::Create(global, impl);
}();
if (NS_WARN_IF(!blob)) {
return false;
}
@ -222,10 +270,6 @@ class ValueDeserializationHelperBase {
INT64_MAX);
MOZ_ASSERT(!blob->IsFile());
// XXX The comment below is somewhat confusing, since it seems to imply
// that this branch is only executed when called from ActorsParent, but
// it's executed from both the parent and the child side code.
// ActorsParent sends here a kind of half blob and half file wrapped into
// a DOM File object. DOM File and DOM Blob are a WebIDL wrapper around a
// BlobImpl object. SetLazyData() has just changed the BlobImpl to be a
@ -251,27 +295,20 @@ class ValueDeserializationHelperBase {
return WrapAsJSObject(aCx, file, aResult);
}
};
template <>
class ValueDeserializationHelper<StructuredCloneFileParent>
: public ValueDeserializationHelperBase {
public:
static bool CreateAndWrapMutableFile(JSContext* aCx,
StructuredCloneFileParent& aFile,
const MutableFileData& aData,
JS::MutableHandle<JSObject*> aResult) {
static bool CreateAndWrapWasmModule(JSContext* aCx,
const StructuredCloneFile& aFile,
const WasmModuleData& aData,
JS::MutableHandle<JSObject*> aResult) {
MOZ_ASSERT(aCx);
MOZ_ASSERT(aFile.Type() == StructuredCloneFileBase::eBlob);
MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eWasmBytecode);
MOZ_ASSERT(!aFile.HasBlob());
// We are in an IDB SQLite schema upgrade where we don't care about a real
// 'MutableFile', but we just care of having a proper |mType| flag.
// Just create a plain object here, support for de-serialization of
// WebAssembly.Modules has been removed in bug 1561876. Full removal is
// tracked in bug 1487479.
aFile.MutateType(StructuredCloneFileBase::eMutableFile);
// Just make a dummy object.
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
if (NS_WARN_IF(!obj)) {
return false;
}
@ -279,85 +316,10 @@ class ValueDeserializationHelper<StructuredCloneFileParent>
aResult.set(obj);
return true;
}
static RefPtr<Blob> GetBlob(JSContext* aCx, IDBDatabase* aDatabase,
const StructuredCloneFileParent& aFile) {
// This is chrome code, so there is no parent, but still we want to set a
// correct parent for the new File object.
const auto global = [aDatabase, aCx]() -> nsCOMPtr<nsIGlobalObject> {
if (NS_IsMainThread()) {
if (aDatabase && aDatabase->GetParentObject()) {
return aDatabase->GetParentObject();
}
return xpc::CurrentNativeGlobal(aCx);
}
const WorkerPrivate* const workerPrivate =
GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
WorkerGlobalScope* const globalScope = workerPrivate->GlobalScope();
MOZ_ASSERT(globalScope);
return do_QueryObject(globalScope);
}();
MOZ_ASSERT(global);
// We do not have an mBlob but do have an FileInfo.
//
// If we are creating an index, we do need a real-looking Blob/File instance
// because the index's key path can reference their properties. Rather than
// create a fake-looking object, create a real Blob.
//
// If we are in a schema upgrade, we don't strictly need that, but we do not
// need to optimize for that, and create it anyway.
const nsCOMPtr<nsIFile> file = aFile.FileInfo().GetFileForFileInfo();
if (!file) {
return nullptr;
}
const auto impl = MakeRefPtr<FileBlobImpl>(file);
impl->SetFileId(aFile.FileInfo().Id());
return File::Create(global, impl);
}
};
template <>
class ValueDeserializationHelper<StructuredCloneFileChild>
: public ValueDeserializationHelperBase {
public:
static bool CreateAndWrapMutableFile(JSContext* aCx,
StructuredCloneFileChild& aFile,
const MutableFileData& aData,
JS::MutableHandle<JSObject*> aResult) {
MOZ_ASSERT(aCx);
MOZ_ASSERT(aFile.Type() == StructuredCloneFileBase::eMutableFile);
// If either MutableFile is disabled (via a pref) and we don't have a
// mutable file here, or we are on a DOM worker and MutableFile is not
// supported on workers, return false to indicate that.
if (!aFile.HasMutableFile() || !NS_IsMainThread()) {
return false;
}
aFile.MutableMutableFile().SetLazyData(aData.name, aData.type);
return WrapAsJSObject(aCx, aFile.MutableMutableFile(), aResult);
}
static RefPtr<Blob> GetBlob(JSContext* aCx, IDBDatabase* aDatabase,
const StructuredCloneFileChild& aFile) {
if (aFile.HasBlob()) {
return aFile.BlobPtr();
}
MOZ_CRASH("Expected a StructuredCloneFile with a Blob");
}
};
} // namespace
template <typename StructuredCloneReadInfo>
JSObject* CommonStructuredCloneReadCallback(
JSContext* aCx, JSStructuredCloneReader* aReader,
const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData,
@ -372,9 +334,6 @@ JSObject* CommonStructuredCloneReadCallback(
"You changed our structured clone tag values and just ate "
"everyone's IndexedDB data. I hope you are happy.");
using StructuredCloneFile =
typename StructuredCloneReadInfo::StructuredCloneFile;
if (aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
aTag == SCTAG_DOM_BLOB || aTag == SCTAG_DOM_FILE ||
aTag == SCTAG_DOM_MUTABLEFILE || aTag == SCTAG_DOM_WASM_MODULE) {
@ -396,10 +355,10 @@ JSObject* CommonStructuredCloneReadCallback(
return nullptr;
}
const auto& file = files[data.bytecodeIndex];
const StructuredCloneFile& file = files[data.bytecodeIndex];
if (NS_WARN_IF(!ValueDeserializationHelper<StructuredCloneFile>::
CreateAndWrapWasmModule(aCx, file, data, &result))) {
if (NS_WARN_IF(!ValueDeserializationHelper::CreateAndWrapWasmModule(
aCx, file, data, &result))) {
return nullptr;
}
@ -411,7 +370,7 @@ JSObject* CommonStructuredCloneReadCallback(
return nullptr;
}
auto& file = aCloneReadInfo->MutableFile(aData);
StructuredCloneFile& file = aCloneReadInfo->MutableFile(aData);
if (aTag == SCTAG_DOM_MUTABLEFILE) {
MutableFileData data;
@ -419,8 +378,8 @@ JSObject* CommonStructuredCloneReadCallback(
return nullptr;
}
if (NS_WARN_IF(!ValueDeserializationHelper<StructuredCloneFile>::
CreateAndWrapMutableFile(aCx, file, data, &result))) {
if (NS_WARN_IF(!ValueDeserializationHelper::CreateAndWrapMutableFile(
aCx, file, data, &result))) {
return nullptr;
}
@ -432,10 +391,8 @@ JSObject* CommonStructuredCloneReadCallback(
return nullptr;
}
if (NS_WARN_IF(!ValueDeserializationHelper<
StructuredCloneFile>::CreateAndWrapBlobOrFile(aCx, aDatabase,
file, data,
&result))) {
if (NS_WARN_IF(!ValueDeserializationHelper::CreateAndWrapBlobOrFile(
aCx, aDatabase, file, data, &result))) {
return nullptr;
}
@ -445,14 +402,4 @@ JSObject* CommonStructuredCloneReadCallback(
return StructuredCloneHolder::ReadFullySerializableObjects(aCx, aReader,
aTag);
}
template JSObject* CommonStructuredCloneReadCallback(
JSContext* aCx, JSStructuredCloneReader* aReader,
const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData,
StructuredCloneReadInfoChild* aCloneReadInfo, IDBDatabase* aDatabase);
template JSObject* CommonStructuredCloneReadCallback(
JSContext* aCx, JSStructuredCloneReader* aReader,
const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData,
StructuredCloneReadInfoParent* aCloneReadInfo, IDBDatabase* aDatabase);
} // namespace mozilla::dom::indexedDB

View File

@ -8,12 +8,11 @@
#define mozilla_dom_indexeddatabase_h__
#include "js/StructuredClone.h"
#include "mozilla/InitializedOnce.h"
#include "mozilla/Variant.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
#include "InitializedOnce.h"
#include "FileInfoFwd.h"
#include "SafeRefPtr.h"
namespace mozilla {
namespace dom {
@ -26,7 +25,7 @@ namespace indexedDB {
class SerializedStructuredCloneReadInfo;
struct StructuredCloneFileBase {
struct StructuredCloneFile {
enum FileType {
eBlob,
eMutableFile,
@ -36,36 +35,47 @@ struct StructuredCloneFileBase {
eEndGuard
};
FileType Type() const { return mType; }
protected:
explicit StructuredCloneFileBase(FileType aType) : mType{aType} {}
FileType mType;
};
struct StructuredCloneFileChild : StructuredCloneFileBase {
StructuredCloneFileChild(const StructuredCloneFileChild&) = delete;
StructuredCloneFileChild& operator=(const StructuredCloneFileChild&) = delete;
StructuredCloneFile(const StructuredCloneFile&) = delete;
StructuredCloneFile& operator=(const StructuredCloneFile&) = delete;
#ifdef NS_BUILD_REFCNT_LOGGING
// In IndexedDatabaseInlines.h
StructuredCloneFileChild(StructuredCloneFileChild&&);
StructuredCloneFile(StructuredCloneFile&&);
#else
StructuredCloneFileChild(StructuredCloneFileChild&&) = default;
StructuredCloneFile(StructuredCloneFile&&) = default;
#endif
StructuredCloneFileChild& operator=(StructuredCloneFileChild&&) = delete;
StructuredCloneFile& operator=(StructuredCloneFile&&) = delete;
// In IndexedDatabaseInlines.h
~StructuredCloneFileChild();
inline explicit StructuredCloneFile(FileType aType);
// In IndexedDatabaseInlines.h
explicit StructuredCloneFileChild(FileType aType);
inline StructuredCloneFile(FileType aType, RefPtr<Blob> aBlob);
// In IndexedDatabaseInlines.h
StructuredCloneFileChild(FileType aType, RefPtr<Blob> aBlob);
inline StructuredCloneFile(FileType aType, RefPtr<FileInfo> aFileInfo);
// In IndexedDatabaseInlines.h
explicit StructuredCloneFileChild(RefPtr<IDBMutableFile> aMutableFile);
inline explicit StructuredCloneFile(RefPtr<IDBMutableFile> aMutableFile);
// In IndexedDatabaseInlines.h
~StructuredCloneFile();
// In IndexedDatabaseInlines.h
inline bool operator==(const StructuredCloneFile& aOther) const;
// XXX This is only needed for a schema upgrade (UpgradeSchemaFrom19_0To20_0).
// If support for older schemas is dropped, we can probably remove this method
// and make mType const.
void MutateType(FileType aNewType) { mType = aNewType; }
FileType Type() const { return mType; }
const indexedDB::FileInfo& FileInfo() const {
return *mContents->as<RefPtr<indexedDB::FileInfo>>();
}
// In IndexedDatabaseInlines.h
RefPtr<indexedDB::FileInfo> FileInfoPtr() const;
const dom::Blob& Blob() const { return *mContents->as<RefPtr<dom::Blob>>(); }
@ -76,7 +86,7 @@ struct StructuredCloneFileChild : StructuredCloneFileBase {
dom::Blob& MutableBlob() const { return *mContents->as<RefPtr<dom::Blob>>(); }
// In IndexedDatabaseInlines.h
RefPtr<dom::Blob> BlobPtr() const;
inline RefPtr<dom::Blob> BlobPtr() const;
bool HasBlob() const { return mContents->is<RefPtr<dom::Blob>>(); }
@ -94,58 +104,13 @@ struct StructuredCloneFileChild : StructuredCloneFileBase {
private:
InitializedOnce<
const Variant<Nothing, RefPtr<dom::Blob>, RefPtr<IDBMutableFile>>>
const Variant<Nothing, RefPtr<dom::Blob>, RefPtr<IDBMutableFile>,
RefPtr<indexedDB::FileInfo>>>
mContents;
FileType mType;
};
struct StructuredCloneFileParent : StructuredCloneFileBase {
StructuredCloneFileParent(const StructuredCloneFileParent&) = delete;
StructuredCloneFileParent& operator=(const StructuredCloneFileParent&) =
delete;
#ifdef NS_BUILD_REFCNT_LOGGING
// In IndexedDatabaseInlines.h
StructuredCloneFileParent(StructuredCloneFileParent&&);
#else
StructuredCloneFileParent(StructuredCloneFileParent&&) = default;
#endif
StructuredCloneFileParent& operator=(StructuredCloneFileParent&&) = delete;
// In IndexedDatabaseInlines.h
StructuredCloneFileParent(FileType aType, SafeRefPtr<FileInfo> aFileInfo);
// In IndexedDatabaseInlines.h
~StructuredCloneFileParent();
// XXX This is used for a schema upgrade hack in UpgradeSchemaFrom19_0To20_0.
// When this is eventually removed, this function can be removed, and mType
// can be declared const in the base class.
void MutateType(FileType aNewType) { mType = aNewType; }
const indexedDB::FileInfo& FileInfo() const { return ***mContents; }
// In IndexedDatabaseInlines.h
SafeRefPtr<indexedDB::FileInfo> FileInfoPtr() const;
private:
InitializedOnce<const Maybe<SafeRefPtr<indexedDB::FileInfo>>> mContents;
};
struct StructuredCloneReadInfoBase {
// In IndexedDatabaseInlines.h
explicit StructuredCloneReadInfoBase(JSStructuredCloneData&& aData)
: mData{std::move(aData)} {}
const JSStructuredCloneData& Data() const { return mData; }
JSStructuredCloneData ReleaseData() { return std::move(mData); }
private:
JSStructuredCloneData mData;
};
template <typename StructuredCloneFileT>
struct StructuredCloneReadInfo : StructuredCloneReadInfoBase {
using StructuredCloneFile = StructuredCloneFileT;
struct StructuredCloneReadInfo {
// In IndexedDatabaseInlines.h
explicit StructuredCloneReadInfo(JS::StructuredCloneScope aScope);
@ -179,6 +144,9 @@ struct StructuredCloneReadInfo : StructuredCloneReadInfoBase {
// In IndexedDatabaseInlines.h
size_t Size() const;
const JSStructuredCloneData& Data() const { return mData; }
JSStructuredCloneData ReleaseData() { return std::move(mData); }
// XXX This is only needed for a schema upgrade (UpgradeSchemaFrom19_0To20_0).
// If support for older schemas is dropped, we can probably remove this method
// and make mFiles InitializedOnce.
@ -192,13 +160,13 @@ struct StructuredCloneReadInfo : StructuredCloneReadInfoBase {
bool HasFiles() const { return !mFiles.IsEmpty(); }
private:
JSStructuredCloneData mData;
nsTArray<StructuredCloneFile> mFiles;
};
struct StructuredCloneReadInfoChild
: StructuredCloneReadInfo<StructuredCloneFileChild> {
struct StructuredCloneReadInfoChild : StructuredCloneReadInfo {
inline StructuredCloneReadInfoChild(JSStructuredCloneData&& aData,
nsTArray<StructuredCloneFileChild> aFiles,
nsTArray<StructuredCloneFile> aFiles,
IDBDatabase* aDatabase);
IDBDatabase* Database() const { return mDatabase; }
@ -209,10 +177,9 @@ struct StructuredCloneReadInfoChild
// This is only defined in the header file to satisfy the clang-plugin static
// analysis, it could be placed in ActorsParent.cpp otherwise.
struct StructuredCloneReadInfoParent
: StructuredCloneReadInfo<StructuredCloneFileParent> {
struct StructuredCloneReadInfoParent : StructuredCloneReadInfo {
StructuredCloneReadInfoParent(JSStructuredCloneData&& aData,
nsTArray<StructuredCloneFileParent> aFiles,
nsTArray<StructuredCloneFile> aFiles,
bool aHasPreprocessInfo)
: StructuredCloneReadInfo{std::move(aData), std::move(aFiles)},
mHasPreprocessInfo{aHasPreprocessInfo} {}
@ -223,7 +190,6 @@ struct StructuredCloneReadInfoParent
bool mHasPreprocessInfo;
};
template <typename StructuredCloneReadInfo>
JSObject* CommonStructuredCloneReadCallback(
JSContext* aCx, JSStructuredCloneReader* aReader,
const JS::CloneDataPolicy& aCloneDataPolicy, uint32_t aTag, uint32_t aData,
@ -239,12 +205,7 @@ JSObject* StructuredCloneReadCallback(
} // namespace dom
} // namespace mozilla
DECLARE_USE_COPY_CONSTRUCTORS(
mozilla::dom::indexedDB::StructuredCloneReadInfo<
mozilla::dom::indexedDB::StructuredCloneFileChild>);
DECLARE_USE_COPY_CONSTRUCTORS(
mozilla::dom::indexedDB::StructuredCloneReadInfo<
mozilla::dom::indexedDB::StructuredCloneFileParent>);
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::indexedDB::StructuredCloneReadInfo);
DECLARE_USE_COPY_CONSTRUCTORS(
mozilla::dom::indexedDB::StructuredCloneReadInfoChild);
DECLARE_USE_COPY_CONSTRUCTORS(

View File

@ -21,108 +21,88 @@ namespace mozilla {
namespace dom {
namespace indexedDB {
#ifdef NS_BUILD_REFCNT_LOGGING
inline StructuredCloneFileChild::StructuredCloneFileChild(
StructuredCloneFileChild&& aOther)
: StructuredCloneFileBase{std::move(aOther)},
mContents{std::move(aOther.mContents)} {
MOZ_COUNT_CTOR(StructuredCloneFileChild);
}
#endif
inline StructuredCloneFileChild::~StructuredCloneFileChild() {
MOZ_COUNT_DTOR(StructuredCloneFileChild);
inline StructuredCloneFile::StructuredCloneFile(FileType aType)
: mContents{Nothing()}, mType{aType} {
MOZ_COUNT_CTOR(StructuredCloneFile);
}
inline StructuredCloneFileChild::StructuredCloneFileChild(FileType aType)
: StructuredCloneFileBase{aType}, mContents{Nothing()} {
MOZ_COUNT_CTOR(StructuredCloneFileChild);
}
inline StructuredCloneFileChild::StructuredCloneFileChild(
FileType aType, RefPtr<dom::Blob> aBlob)
: StructuredCloneFileBase{aType}, mContents{std::move(aBlob)} {
inline StructuredCloneFile::StructuredCloneFile(FileType aType,
RefPtr<dom::Blob> aBlob)
: mContents{std::move(aBlob)}, mType{aType} {
MOZ_ASSERT(eBlob == aType || eStructuredClone == aType);
MOZ_ASSERT(mContents->as<RefPtr<dom::Blob>>());
MOZ_COUNT_CTOR(StructuredCloneFileChild);
MOZ_COUNT_CTOR(StructuredCloneFile);
}
inline StructuredCloneFileParent::StructuredCloneFileParent(
FileType aType, SafeRefPtr<indexedDB::FileInfo> aFileInfo)
: StructuredCloneFileBase{aType}, mContents{Some(std::move(aFileInfo))} {
MOZ_ASSERT(**mContents);
MOZ_COUNT_CTOR(StructuredCloneFileParent);
inline StructuredCloneFile::StructuredCloneFile(
FileType aType, RefPtr<indexedDB::FileInfo> aFileInfo)
: mContents{std::move(aFileInfo)}, mType{aType} {
MOZ_ASSERT(mContents->as<RefPtr<indexedDB::FileInfo>>());
MOZ_COUNT_CTOR(StructuredCloneFile);
}
inline StructuredCloneFileChild::StructuredCloneFileChild(
inline StructuredCloneFile::StructuredCloneFile(
RefPtr<IDBMutableFile> aMutableFile)
: StructuredCloneFileBase{eMutableFile},
mContents{std::move(aMutableFile)} {
: mContents{std::move(aMutableFile)}, mType{eMutableFile} {
MOZ_ASSERT(mContents->as<RefPtr<IDBMutableFile>>());
MOZ_COUNT_CTOR(StructuredCloneFileChild);
MOZ_COUNT_CTOR(StructuredCloneFile);
}
#ifdef NS_BUILD_REFCNT_LOGGING
inline StructuredCloneFileParent::StructuredCloneFileParent(
StructuredCloneFileParent&& aOther)
: StructuredCloneFileBase{std::move(aOther)},
mContents{std::move(aOther.mContents)} {
MOZ_COUNT_CTOR(StructuredCloneFileParent);
inline StructuredCloneFile::StructuredCloneFile(StructuredCloneFile&& aOther)
: mContents{std::move(aOther.mContents)}, mType{aOther.mType} {
MOZ_COUNT_CTOR(StructuredCloneFile);
}
#endif
inline StructuredCloneFileParent::~StructuredCloneFileParent() {
MOZ_COUNT_DTOR(StructuredCloneFileParent);
inline StructuredCloneFile::~StructuredCloneFile() {
MOZ_COUNT_DTOR(StructuredCloneFile);
}
inline SafeRefPtr<indexedDB::FileInfo> StructuredCloneFileParent::FileInfoPtr()
const {
return (*mContents)->clonePtr();
inline RefPtr<indexedDB::FileInfo> StructuredCloneFile::FileInfoPtr() const {
return mContents->as<RefPtr<indexedDB::FileInfo>>();
}
inline RefPtr<dom::Blob> StructuredCloneFileChild::BlobPtr() const {
inline RefPtr<dom::Blob> StructuredCloneFile::BlobPtr() const {
return mContents->as<RefPtr<dom::Blob>>();
}
template <typename StructuredCloneFile>
inline StructuredCloneReadInfo<StructuredCloneFile>::StructuredCloneReadInfo(
inline bool StructuredCloneFile::operator==(
const StructuredCloneFile& aOther) const {
return this->mType == aOther.mType && *this->mContents == *aOther.mContents;
}
inline StructuredCloneReadInfo::StructuredCloneReadInfo(
JS::StructuredCloneScope aScope)
: StructuredCloneReadInfoBase(JSStructuredCloneData{aScope}) {
: mData(aScope) {
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
}
template <typename StructuredCloneFile>
inline StructuredCloneReadInfo<StructuredCloneFile>::StructuredCloneReadInfo()
inline StructuredCloneReadInfo::StructuredCloneReadInfo()
: StructuredCloneReadInfo(
JS::StructuredCloneScope::DifferentProcessForIndexedDB) {}
template <typename StructuredCloneFile>
inline StructuredCloneReadInfo<StructuredCloneFile>::StructuredCloneReadInfo(
inline StructuredCloneReadInfo::StructuredCloneReadInfo(
JSStructuredCloneData&& aData, nsTArray<StructuredCloneFile> aFiles)
: StructuredCloneReadInfoBase{std::move(aData)}, mFiles{std::move(aFiles)} {
: mData{std::move(aData)}, mFiles{std::move(aFiles)} {
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
}
#ifdef NS_BUILD_REFCNT_LOGGING
template <typename StructuredCloneFile>
inline StructuredCloneReadInfo<StructuredCloneFile>::StructuredCloneReadInfo(
inline StructuredCloneReadInfo::StructuredCloneReadInfo(
StructuredCloneReadInfo&& aOther) noexcept
: StructuredCloneReadInfoBase{std::move(aOther)},
mFiles{std::move(aOther.mFiles)} {
: mData{std::move(aOther.mData)}, mFiles{std::move(aOther.mFiles)} {
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
}
template <typename StructuredCloneFile>
inline StructuredCloneReadInfo<
StructuredCloneFile>::~StructuredCloneReadInfo() {
inline StructuredCloneReadInfo::~StructuredCloneReadInfo() {
MOZ_COUNT_DTOR(StructuredCloneReadInfo);
}
#endif
template <typename StructuredCloneFile>
inline size_t StructuredCloneReadInfo<StructuredCloneFile>::Size() const {
size_t size = Data().Size();
inline size_t StructuredCloneReadInfo::Size() const {
size_t size = mData.Size();
for (uint32_t i = 0, count = mFiles.Length(); i < count; ++i) {
// We don't want to calculate the size of files and so on, because are
@ -134,7 +114,7 @@ inline size_t StructuredCloneReadInfo<StructuredCloneFile>::Size() const {
}
inline StructuredCloneReadInfoChild::StructuredCloneReadInfoChild(
JSStructuredCloneData&& aData, nsTArray<StructuredCloneFileChild> aFiles,
JSStructuredCloneData&& aData, nsTArray<StructuredCloneFile> aFiles,
IDBDatabase* aDatabase)
: StructuredCloneReadInfo{std::move(aData), std::move(aFiles)},
mDatabase{aDatabase} {}
@ -172,7 +152,7 @@ JSObject* StructuredCloneReadCallback(
}();
return CommonStructuredCloneReadCallback(
aCx, aReader, aCloneDataPolicy, aTag, aData,
static_cast<StructuredCloneReadInfoType*>(aClosure), database);
static_cast<StructuredCloneReadInfo*>(aClosure), database);
}
template <typename T>

View File

@ -60,10 +60,10 @@ using namespace mozilla::ipc;
class FileManagerInfo {
public:
MOZ_MUST_USE SafeRefPtr<FileManager> GetFileManager(
MOZ_MUST_USE RefPtr<FileManager> GetFileManager(
PersistenceType aPersistenceType, const nsAString& aName) const;
void AddFileManager(SafeRefPtr<FileManager> aFileManager);
void AddFileManager(FileManager* aFileManager);
bool HasFileManagers() const {
AssertIsOnIOThread();
@ -81,17 +81,16 @@ class FileManagerInfo {
const nsAString& aName);
private:
nsTArray<SafeRefPtr<FileManager> >& GetArray(
PersistenceType aPersistenceType);
nsTArray<RefPtr<FileManager> >& GetArray(PersistenceType aPersistenceType);
const nsTArray<SafeRefPtr<FileManager> >& GetImmutableArray(
const nsTArray<RefPtr<FileManager> >& GetImmutableArray(
PersistenceType aPersistenceType) const {
return const_cast<FileManagerInfo*>(this)->GetArray(aPersistenceType);
}
nsTArray<SafeRefPtr<FileManager> > mPersistentStorageFileManagers;
nsTArray<SafeRefPtr<FileManager> > mTemporaryStorageFileManagers;
nsTArray<SafeRefPtr<FileManager> > mDefaultStorageFileManagers;
nsTArray<RefPtr<FileManager> > mPersistentStorageFileManagers;
nsTArray<RefPtr<FileManager> > mTemporaryStorageFileManagers;
nsTArray<RefPtr<FileManager> > mDefaultStorageFileManagers;
};
} // namespace indexedDB
@ -680,7 +679,7 @@ void IndexedDatabaseManager::ClearBackgroundActor() {
mBackgroundActor = nullptr;
}
SafeRefPtr<FileManager> IndexedDatabaseManager::GetFileManager(
RefPtr<FileManager> IndexedDatabaseManager::GetFileManager(
PersistenceType aPersistenceType, const nsACString& aOrigin,
const nsAString& aDatabaseName) {
AssertIsOnIOThread();
@ -693,8 +692,7 @@ SafeRefPtr<FileManager> IndexedDatabaseManager::GetFileManager(
return info->GetFileManager(aPersistenceType, aDatabaseName);
}
void IndexedDatabaseManager::AddFileManager(
SafeRefPtr<FileManager> aFileManager) {
void IndexedDatabaseManager::AddFileManager(FileManager* aFileManager) {
AssertIsOnIOThread();
NS_ASSERTION(aFileManager, "Null file manager!");
@ -704,7 +702,7 @@ void IndexedDatabaseManager::AddFileManager(
mFileManagerInfos.Put(aFileManager->Origin(), info);
}
info->AddFileManager(std::move(aFileManager));
info->AddFileManager(aFileManager);
}
void IndexedDatabaseManager::InvalidateAllFileManagers() {
@ -857,7 +855,7 @@ const nsCString& IndexedDatabaseManager::GetLocale() {
return idbManager->mLocale;
}
SafeRefPtr<FileManager> FileManagerInfo::GetFileManager(
RefPtr<FileManager> FileManagerInfo::GetFileManager(
PersistenceType aPersistenceType, const nsAString& aName) const {
AssertIsOnIOThread();
@ -867,17 +865,17 @@ SafeRefPtr<FileManager> FileManagerInfo::GetFileManager(
const auto foundIt =
std::find_if(managers.cbegin(), end, DatabaseNameMatchPredicate(&aName));
return foundIt != end ? foundIt->clonePtr() : nullptr;
return foundIt != end ? *foundIt : nullptr;
}
void FileManagerInfo::AddFileManager(SafeRefPtr<FileManager> aFileManager) {
void FileManagerInfo::AddFileManager(FileManager* aFileManager) {
AssertIsOnIOThread();
nsTArray<SafeRefPtr<FileManager> >& managers = GetArray(aFileManager->Type());
nsTArray<RefPtr<FileManager> >& managers = GetArray(aFileManager->Type());
NS_ASSERTION(!managers.Contains(aFileManager), "Adding more than once?!");
managers.AppendElement(std::move(aFileManager));
managers.AppendElement(aFileManager);
}
void FileManagerInfo::InvalidateAllFileManagers() const {
@ -902,7 +900,7 @@ void FileManagerInfo::InvalidateAndRemoveFileManagers(
PersistenceType aPersistenceType) {
AssertIsOnIOThread();
nsTArray<SafeRefPtr<FileManager> >& managers = GetArray(aPersistenceType);
nsTArray<RefPtr<FileManager> >& managers = GetArray(aPersistenceType);
for (uint32_t i = 0; i < managers.Length(); i++) {
managers[i]->Invalidate();
@ -926,7 +924,7 @@ void FileManagerInfo::InvalidateAndRemoveFileManager(
}
}
nsTArray<SafeRefPtr<FileManager> >& FileManagerInfo::GetArray(
nsTArray<RefPtr<FileManager> >& FileManagerInfo::GetArray(
PersistenceType aPersistenceType) {
switch (aPersistenceType) {
case PERSISTENCE_TYPE_PERSISTENT:

View File

@ -13,7 +13,6 @@
#include "mozilla/Mutex.h"
#include "nsClassHashtable.h"
#include "nsHashKeys.h"
#include "SafeRefPtr.h"
namespace mozilla {
@ -104,11 +103,11 @@ class IndexedDatabaseManager final {
void ClearBackgroundActor();
MOZ_MUST_USE SafeRefPtr<FileManager> GetFileManager(
MOZ_MUST_USE RefPtr<FileManager> GetFileManager(
PersistenceType aPersistenceType, const nsACString& aOrigin,
const nsAString& aDatabaseName);
void AddFileManager(SafeRefPtr<FileManager> aFileManager);
void AddFileManager(FileManager* aFileManager);
void InvalidateAllFileManagers();

View File

@ -0,0 +1,149 @@
/* -*- 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_initializedonce_h__
#define mozilla_dom_indexeddb_initializedonce_h__
#include "mozilla/Assertions.h"
#include "mozilla/Maybe.h"
#include <type_traits>
// This file is not exported and is only meant to be included in IndexedDB
// source files.
// TODO: However, it is meant to be moved to mfbt, and therefore already placed
// in the mozilla namespace.
namespace mozilla {
enum struct LazyInit { Allow, AllowResettable, ForbidResettable };
namespace ValueCheckPolicies {
template <typename T>
struct AllowAnyValue {
constexpr static bool Check(const T& /*aValue*/) { return true; }
};
template <typename T>
struct ConvertsToTrue {
constexpr static bool Check(const T& aValue) {
return static_cast<bool>(aValue);
}
};
} // namespace ValueCheckPolicies
// A kind of mozilla::Maybe that can only be initialized and cleared once. It
// cannot be re-initialized. This is a more stateful than a const Maybe<T> in
// that it can be cleared, but much less stateful than a non-const Maybe<T>
// which could be reinitialized multiple times. Can only be used with const T
// to ensure that the contents cannot be modified either.
// TODO: Make constructors constexpr when Maybe's constructors are constexpr
// (Bug 1601336).
template <typename T, LazyInit LazyInitVal = LazyInit::ForbidResettable,
template <typename> class ValueCheckPolicy =
ValueCheckPolicies::AllowAnyValue>
class InitializedOnce final {
static_assert(std::is_const_v<T>);
public:
template <typename Dummy = void>
explicit InitializedOnce(
std::enable_if_t<LazyInitVal == LazyInit::Allow ||
LazyInitVal == LazyInit::AllowResettable,
Dummy>* = nullptr) {}
template <typename Arg0, typename... Args>
explicit InitializedOnce(Arg0&& aArg0, Args&&... aArgs)
: mMaybe{Some(std::remove_const_t<T>{std::forward<Arg0>(aArg0),
std::forward<Args>(aArgs)...})} {
MOZ_ASSERT(ValueCheckPolicy<T>::Check(*mMaybe));
}
InitializedOnce(const InitializedOnce&) = delete;
InitializedOnce(InitializedOnce&& aOther) : mMaybe{std::move(aOther.mMaybe)} {
static_assert(LazyInitVal == LazyInit::AllowResettable ||
LazyInitVal == LazyInit::ForbidResettable);
#ifdef DEBUG
aOther.mWasReset = true;
#endif
}
InitializedOnce& operator=(const InitializedOnce&) = delete;
InitializedOnce& operator=(InitializedOnce&& aOther) {
static_assert(LazyInitVal == LazyInit::AllowResettable);
MOZ_ASSERT(!mWasReset);
MOZ_ASSERT(!mMaybe);
mMaybe.~Maybe<std::remove_const_t<T>>();
new (&mMaybe) Maybe<T>{std::move(aOther.mMaybe)};
#ifdef DEBUG
aOther.mWasReset = true;
#endif
return *this;
}
template <typename... Args, typename Dummy = void>
std::enable_if_t<LazyInitVal == LazyInit::Allow ||
LazyInitVal == LazyInit::AllowResettable,
Dummy>
init(Args&&... aArgs) {
MOZ_ASSERT(mMaybe.isNothing());
MOZ_ASSERT(!mWasReset);
mMaybe.emplace(std::remove_const_t<T>{std::forward<Args>(aArgs)...});
MOZ_ASSERT(ValueCheckPolicy<T>::Check(*mMaybe));
}
explicit operator bool() const { return isSome(); }
bool isSome() const { return mMaybe.isSome(); }
bool isNothing() const { return mMaybe.isNothing(); }
T& operator*() const { return *mMaybe; }
T* operator->() const { return mMaybe.operator->(); }
template <typename Dummy = void>
std::enable_if_t<LazyInitVal == LazyInit::AllowResettable ||
LazyInitVal == LazyInit::ForbidResettable,
Dummy>
reset() {
MOZ_ASSERT(mMaybe.isSome());
maybeReset();
}
template <typename Dummy = void>
std::enable_if_t<LazyInitVal == LazyInit::AllowResettable ||
LazyInitVal == LazyInit::ForbidResettable,
Dummy>
maybeReset() {
mMaybe.reset();
#ifdef DEBUG
mWasReset = true;
#endif
}
template <typename Dummy = T>
std::enable_if_t<LazyInitVal == LazyInit::AllowResettable ||
LazyInitVal == LazyInit::ForbidResettable,
Dummy>
release() {
MOZ_ASSERT(mMaybe.isSome());
auto res = std::move(mMaybe.ref());
maybeReset();
return res;
}
private:
Maybe<std::remove_const_t<T>> mMaybe;
#ifdef DEBUG
bool mWasReset = false;
#endif
};
template <typename T, LazyInit LazyInitVal = LazyInit::ForbidResettable>
using InitializedOnceMustBeTrue =
InitializedOnce<T, LazyInitVal, ValueCheckPolicies::ConvertsToTrue>;
} // namespace mozilla
#endif

View File

@ -25,7 +25,7 @@ using struct mozilla::void_t
using mozilla::dom::IDBCursor::Direction
from "mozilla/dom/IDBCursor.h";
using mozilla::dom::indexedDB::StructuredCloneFileBase::FileType
using mozilla::dom::indexedDB::StructuredCloneFile::FileType
from "mozilla/dom/IndexedDatabase.h";
using class mozilla::dom::indexedDB::Key

View File

@ -1,185 +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_saferefptr_h__
#define mozilla_saferefptr_h__
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
namespace mozilla {
struct AcquireStrongRefFromRawPtr {};
// A restricted variant of mozilla::RefPtr<T>, which prohibits some unsafe or
// unperformant misuses, in particular:
// * It is not implicitly convertible from a raw pointer. Unsafe acquisitions
// from a raw pointer must be made using the verbose
// AcquireStrongRefFromRawPtr. To create a new object on the heap, use
// MakeSafeRefPtr.
// * It does not implicitly decay to a raw pointer. get() must be called
// explicitly.
// * It is not copyable, but must be explicitly copied using clonePtr().
// * Temporaries cannot be dereferenced using operator* or operator->.
template <class T>
class MOZ_IS_REFPTR SafeRefPtr {
template <class U>
friend class SafeRefPtr;
RefPtr<T> mRefPtr;
public:
SafeRefPtr() = default;
template <typename U,
typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
MOZ_IMPLICIT SafeRefPtr(SafeRefPtr<U>&& aSrc)
: mRefPtr(std::move(aSrc.mRefPtr)) {}
explicit SafeRefPtr(RefPtr<T>&& aRefPtr) : mRefPtr(std::move(aRefPtr)) {}
// To prevent implicit conversion of raw pointer to RefPtr and then
// calling the previous overload.
SafeRefPtr(T* const aRawPtr) = delete;
SafeRefPtr(T* const aRawPtr, const AcquireStrongRefFromRawPtr&)
: mRefPtr(aRawPtr) {}
MOZ_IMPLICIT SafeRefPtr(std::nullptr_t) {}
// Prevent implicit copying, use clonePtr() instead.
SafeRefPtr(const SafeRefPtr&) = delete;
SafeRefPtr& operator=(const SafeRefPtr&) = delete;
// Allow moving.
SafeRefPtr(SafeRefPtr&&) = default;
SafeRefPtr& operator=(SafeRefPtr&&) = default;
typedef T element_type;
explicit operator bool() const { return mRefPtr; }
bool operator!() const { return !mRefPtr; }
T& operator*() const&& = delete;
T& operator*() const& { return mRefPtr.operator*(); }
T* operator->() const&& = delete;
T* operator->() const& MOZ_NO_ADDREF_RELEASE_ON_RETURN {
return mRefPtr.operator->();
}
Maybe<T&> maybeDeref() const {
return mRefPtr ? SomeRef(*mRefPtr) : Nothing();
}
T* unsafeGetRawPtr() const { return mRefPtr.get(); }
SafeRefPtr<T> clonePtr() const { return SafeRefPtr{RefPtr{mRefPtr}}; }
already_AddRefed<T> forget() { return mRefPtr.forget(); }
bool operator==(const SafeRefPtr<T>& aOther) const {
return mRefPtr == aOther.mRefPtr;
}
bool operator!=(const SafeRefPtr<T>& aOther) const {
return mRefPtr != aOther.mRefPtr;
}
template <typename U>
friend RefPtr<U> AsRefPtr(SafeRefPtr<U>&& aSafeRefPtr);
};
template <typename T>
SafeRefPtr(RefPtr<T> &&)->SafeRefPtr<T>;
template <typename T>
bool operator==(std::nullptr_t aLhs, const SafeRefPtr<T>& aRhs) {
return !aRhs;
}
template <typename T>
bool operator!=(std::nullptr_t aLhs, const SafeRefPtr<T>& aRhs) {
return static_cast<bool>(aRhs);
}
template <typename T>
bool operator==(const SafeRefPtr<T>& aLhs, std::nullptr_t aRhs) {
return !aLhs;
}
template <typename T>
bool operator!=(const SafeRefPtr<T>& aLhs, std::nullptr_t aRhs) {
return static_cast<bool>(aLhs);
}
template <typename T, typename U, typename = std::common_type_t<T*, U*>>
bool operator==(T* const aLhs, const SafeRefPtr<U>& aRhs) {
return aLhs == aRhs.unsafeGetRawPtr();
}
template <typename T, typename U, typename = std::common_type_t<T*, U*>>
bool operator!=(T* const aLhs, const SafeRefPtr<U>& aRhs) {
return !(aLhs == aRhs);
}
template <typename T, typename U, typename = std::common_type_t<T*, U*>>
bool operator==(const SafeRefPtr<T>& aLhs, U* const aRhs) {
return aRhs == aLhs;
}
template <typename T, typename U, typename = std::common_type_t<T*, U*>>
bool operator!=(const SafeRefPtr<T>& aLhs, U* const aRhs) {
return aRhs != aLhs;
}
template <typename T, typename U, typename = std::common_type_t<T*, U*>>
bool operator==(const Maybe<T&> aLhs, const SafeRefPtr<U>& aRhs) {
return &aLhs.ref() == aRhs.unsafeGetRawPtr();
}
template <typename T, typename U, typename = std::common_type_t<T*, U*>>
bool operator!=(const Maybe<T&> aLhs, const SafeRefPtr<U>& aRhs) {
return !(aLhs == aRhs);
}
template <typename T, typename U, typename = std::common_type_t<T*, U*>>
bool operator==(const SafeRefPtr<T>& aLhs, const Maybe<U&> aRhs) {
return aRhs == aLhs;
}
template <typename T, typename U, typename = std::common_type_t<T*, U*>>
bool operator!=(const SafeRefPtr<T>& aLhs, const Maybe<U&> aRhs) {
return aRhs != aLhs;
}
template <typename T>
RefPtr<T> AsRefPtr(SafeRefPtr<T>&& aSafeRefPtr) {
return std::move(aSafeRefPtr.mRefPtr);
}
template <typename T, typename... Args>
SafeRefPtr<T> MakeSafeRefPtr(Args&&... aArgs) {
return SafeRefPtr{MakeRefPtr<T>(std::forward<Args>(aArgs)...)};
}
template <typename T>
void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
const SafeRefPtr<T>& aField, const char* aName,
uint32_t aFlags = 0) {
CycleCollectionNoteChild(aCallback, aField.unsafeGetRawPtr(), aName, aFlags);
}
template <typename T>
void ImplCycleCollectionUnlink(SafeRefPtr<T>& aField) {
aField = nullptr;
}
} // namespace mozilla
#endif

View File

@ -17,11 +17,11 @@
namespace IPC {
template <>
struct ParamTraits<mozilla::dom::indexedDB::StructuredCloneFileBase::FileType>
struct ParamTraits<mozilla::dom::indexedDB::StructuredCloneFile::FileType>
: public ContiguousEnumSerializer<
mozilla::dom::indexedDB::StructuredCloneFileBase::FileType,
mozilla::dom::indexedDB::StructuredCloneFileBase::eBlob,
mozilla::dom::indexedDB::StructuredCloneFileBase::eEndGuard> {};
mozilla::dom::indexedDB::StructuredCloneFile::FileType,
mozilla::dom::indexedDB::StructuredCloneFile::eBlob,
mozilla::dom::indexedDB::StructuredCloneFile::eEndGuard> {};
template <>
struct ParamTraits<mozilla::dom::indexedDB::Key> {

View File

@ -41,7 +41,7 @@ EXPORTS.mozilla.dom += [
'IDBTransaction.h',
'IndexedDatabase.h',
'IndexedDatabaseManager.h',
'SafeRefPtr.h',
'InitializedOnce.h',
]
EXPORTS.mozilla.dom.indexedDB += [

View File

@ -57,10 +57,8 @@ class TestFileManager final : public FileManagerBase<TestFileManager> {
for (const auto id : kDBOnlyFileInfoIds) {
// Copied from within FileManager::Init.
mFileInfos.Put(
id, new FileInfo(FileManagerGuard{},
SafeRefPtr{this, AcquireStrongRefFromRawPtr{}}, id,
static_cast<nsrefcnt>(1)));
mFileInfos.Put(id, new FileInfo(FileManagerGuard{}, this, id,
static_cast<nsrefcnt>(1)));
mLastFileId = std::max(id, mLastFileId);
}
@ -108,7 +106,7 @@ TEST(DOM_IndexedDB_FileInfo, Create)
int32_t memRefCnt, dbRefCnt;
fileInfo->GetReferences(&memRefCnt, &dbRefCnt);
ASSERT_EQ(fileManager, &fileInfo->Manager());
ASSERT_EQ(fileManager, fileInfo->Manager());
ASSERT_EQ(1, memRefCnt);
ASSERT_EQ(0, dbRefCnt);
@ -133,7 +131,7 @@ TEST(DOM_IndexedDB_FileInfo, CreateWithInitialDBRefCnt)
int32_t memRefCnt, dbRefCnt;
fileInfo->GetReferences(&memRefCnt, &dbRefCnt);
ASSERT_EQ(fileManager, &fileInfo->Manager());
ASSERT_EQ(fileManager, fileInfo->Manager());
ASSERT_EQ(1, memRefCnt); // we hold one in fileInfo ourselves
ASSERT_EQ(1, dbRefCnt);
@ -153,7 +151,7 @@ TEST(DOM_IndexedDB_FileInfo, CreateWithInitialDBRefCnt_Invalidate)
const auto fileManager = MakeRefPtr<TestFileManager>(&stats);
fileManager->CreateDBOnlyFileInfos();
auto fileInfos = nsTArray<SafeRefPtr<TestFileInfo>>{};
auto fileInfos = nsTArray<RefPtr<TestFileInfo>>{};
for (const auto id : TestFileManager::kDBOnlyFileInfoIds) {
fileInfos.EmplaceBack(fileManager->GetFileInfo(id));
}