Bug 1809043 - Create a dedicated parent object for access handles independent from IPC; r=dom-storage-reviewers,jari

Parent objects are usually actors as well, but the access handle is special
because it will need to have multiple actors.

Depends on D166297

Differential Revision: https://phabricator.services.mozilla.com/D166298
This commit is contained in:
Jan Varga 2023-02-02 12:02:13 +00:00
Родитель 19d608932e
Коммит 002b7d3f4c
6 изменённых файлов: 141 добавлений и 47 удалений

Просмотреть файл

@ -0,0 +1,57 @@
/* -*- 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/. */
#include "FileSystemAccessHandle.h"
#include "mozilla/Result.h"
#include "mozilla/dom/FileSystemDataManager.h"
#include "mozilla/dom/FileSystemLog.h"
namespace mozilla::dom {
FileSystemAccessHandle::FileSystemAccessHandle(
RefPtr<fs::data::FileSystemDataManager> aDataManager,
const fs::EntryId& aEntryId)
: mEntryId(aEntryId),
mDataManager(std::move(aDataManager)),
mClosed(false) {}
FileSystemAccessHandle::~FileSystemAccessHandle() {
if (IsOpen()) {
Close();
}
}
// static
Result<RefPtr<FileSystemAccessHandle>, nsresult> FileSystemAccessHandle::Create(
RefPtr<fs::data::FileSystemDataManager> aDataManager,
const fs::EntryId& aEntryId) {
MOZ_ASSERT(aDataManager);
aDataManager->AssertIsOnIOTarget();
if (!aDataManager->LockExclusive(aEntryId)) {
return Err(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
}
RefPtr<FileSystemAccessHandle> accessHandle =
new FileSystemAccessHandle(std::move(aDataManager), aEntryId);
return accessHandle;
}
bool FileSystemAccessHandle::IsOpen() const { return !mClosed; }
void FileSystemAccessHandle::Close() {
MOZ_ASSERT(!mClosed);
LOG(("Closing AccessHandle"));
mClosed = true;
mDataManager->UnlockExclusive(mEntryId);
}
} // namespace mozilla::dom

Просмотреть файл

@ -0,0 +1,56 @@
/* -*- 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 DOM_FS_PARENT_FILESYSTEMACCESSHANDLE_H_
#define DOM_FS_PARENT_FILESYSTEMACCESSHANDLE_H_
#include "mozilla/RefPtr.h"
#include "mozilla/dom/FileSystemTypes.h"
#include "nsISupportsUtils.h"
#include "nsString.h"
enum class nsresult : uint32_t;
namespace mozilla {
template <typename V, typename E>
class Result;
namespace dom {
namespace fs::data {
class FileSystemDataManager;
} // namespace fs::data
class FileSystemAccessHandle {
public:
static Result<RefPtr<FileSystemAccessHandle>, nsresult> Create(
RefPtr<fs::data::FileSystemDataManager> aDataManager,
const fs::EntryId& aEntryId);
NS_INLINE_DECL_REFCOUNTING_ONEVENTTARGET(FileSystemAccessHandle)
bool IsOpen() const;
void Close();
private:
FileSystemAccessHandle(RefPtr<fs::data::FileSystemDataManager> aDataManager,
const fs::EntryId& aEntryId);
~FileSystemAccessHandle();
const fs::EntryId mEntryId;
RefPtr<fs::data::FileSystemDataManager> mDataManager;
bool mClosed;
};
} // namespace dom
} // namespace mozilla
#endif // DOM_FS_PARENT_FILESYSTEMACCESSHANDLE_H_

Просмотреть файл

@ -6,38 +6,30 @@
#include "FileSystemAccessHandleParent.h" #include "FileSystemAccessHandleParent.h"
#include "FileSystemDataManager.h" #include "mozilla/dom/FileSystemAccessHandle.h"
#include "mozilla/dom/FileSystemLog.h"
#include "mozilla/dom/FileSystemManagerParent.h"
namespace mozilla::dom { namespace mozilla::dom {
FileSystemAccessHandleParent::FileSystemAccessHandleParent( FileSystemAccessHandleParent::FileSystemAccessHandleParent(
RefPtr<FileSystemManagerParent> aManager, const fs::EntryId& aEntryId) RefPtr<FileSystemAccessHandle> aAccessHandle)
: mManager(std::move(aManager)), mEntryId(aEntryId) {} : mAccessHandle(std::move(aAccessHandle)) {}
FileSystemAccessHandleParent::~FileSystemAccessHandleParent() { FileSystemAccessHandleParent::~FileSystemAccessHandleParent() {
MOZ_ASSERT(mClosed); MOZ_ASSERT(mActorDestroyed);
} }
mozilla::ipc::IPCResult FileSystemAccessHandleParent::RecvClose() { mozilla::ipc::IPCResult FileSystemAccessHandleParent::RecvClose() {
Close(); mAccessHandle->Close();
return IPC_OK(); return IPC_OK();
} }
void FileSystemAccessHandleParent::ActorDestroy(ActorDestroyReason aWhy) { void FileSystemAccessHandleParent::ActorDestroy(ActorDestroyReason aWhy) {
if (!IsClosed()) { MOZ_ASSERT(!mActorDestroyed);
Close();
}
}
void FileSystemAccessHandleParent::Close() { DEBUGONLY(mActorDestroyed = true);
LOG(("Closing SyncAccessHandle"));
mClosed.Flip(); mAccessHandle = nullptr;
mManager->DataManagerStrongRef()->UnlockExclusive(mEntryId);
} }
} // namespace mozilla::dom } // namespace mozilla::dom

Просмотреть файл

@ -7,18 +7,17 @@
#ifndef DOM_FS_PARENT_FILESYSTEMACCESSHANDLEPARENT_H_ #ifndef DOM_FS_PARENT_FILESYSTEMACCESSHANDLEPARENT_H_
#define DOM_FS_PARENT_FILESYSTEMACCESSHANDLEPARENT_H_ #define DOM_FS_PARENT_FILESYSTEMACCESSHANDLEPARENT_H_
#include "mozilla/dom/FileSystemTypes.h"
#include "mozilla/dom/FlippedOnce.h"
#include "mozilla/dom/PFileSystemAccessHandleParent.h" #include "mozilla/dom/PFileSystemAccessHandleParent.h"
#include "mozilla/dom/quota/DebugOnlyMacro.h"
namespace mozilla::dom { namespace mozilla::dom {
class FileSystemManagerParent; class FileSystemAccessHandle;
class FileSystemAccessHandleParent : public PFileSystemAccessHandleParent { class FileSystemAccessHandleParent : public PFileSystemAccessHandleParent {
public: public:
FileSystemAccessHandleParent(RefPtr<FileSystemManagerParent> aManager, explicit FileSystemAccessHandleParent(
const fs::EntryId& aEntryId); RefPtr<FileSystemAccessHandle> aAccessHandle);
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileSystemAccessHandleParent, override) NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileSystemAccessHandleParent, override)
@ -29,15 +28,9 @@ class FileSystemAccessHandleParent : public PFileSystemAccessHandleParent {
private: private:
virtual ~FileSystemAccessHandleParent(); virtual ~FileSystemAccessHandleParent();
bool IsClosed() const { return mClosed; } RefPtr<FileSystemAccessHandle> mAccessHandle;
void Close(); DEBUGONLY(bool mActorDestroyed = false);
const RefPtr<FileSystemManagerParent> mManager;
const fs::EntryId mEntryId;
FlippedOnce<false> mClosed;
}; };
} // namespace mozilla::dom } // namespace mozilla::dom

Просмотреть файл

@ -10,6 +10,7 @@
#include "FileSystemStreamCallbacks.h" #include "FileSystemStreamCallbacks.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "mozilla/dom/FileBlobImpl.h" #include "mozilla/dom/FileBlobImpl.h"
#include "mozilla/dom/FileSystemAccessHandle.h"
#include "mozilla/dom/FileSystemAccessHandleParent.h" #include "mozilla/dom/FileSystemAccessHandleParent.h"
#include "mozilla/dom/FileSystemDataManager.h" #include "mozilla/dom/FileSystemDataManager.h"
#include "mozilla/dom/FileSystemLog.h" #include "mozilla/dom/FileSystemLog.h"
@ -119,17 +120,15 @@ mozilla::ipc::IPCResult FileSystemManagerParent::RecvGetAccessHandle(
AssertIsOnIOTarget(); AssertIsOnIOTarget();
MOZ_ASSERT(mDataManager); MOZ_ASSERT(mDataManager);
if (!mDataManager->LockExclusive(aRequest.entryId())) { auto resolveAndReturn = [aResolver](nsresult rv) {
aResolver(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); aResolver(rv);
return IPC_OK(); return IPC_OK();
} };
auto autoUnlock = QM_TRY_UNWRAP(
MakeScopeExit([self = RefPtr<FileSystemManagerParent>(this), aRequest] { RefPtr<FileSystemAccessHandle> accessHandle,
self->mDataManager->UnlockExclusive(aRequest.entryId()); FileSystemAccessHandle::Create(mDataManager, aRequest.entryId()),
}); resolveAndReturn);
auto reportError = [aResolver](nsresult rv) { aResolver(rv); };
nsString type; nsString type;
fs::TimeStamp lastModifiedMilliSeconds; fs::TimeStamp lastModifiedMilliSeconds;
@ -137,7 +136,7 @@ mozilla::ipc::IPCResult FileSystemManagerParent::RecvGetAccessHandle(
nsCOMPtr<nsIFile> file; nsCOMPtr<nsIFile> file;
QM_TRY(MOZ_TO_RESULT(mDataManager->MutableDatabaseManagerPtr()->GetFile( QM_TRY(MOZ_TO_RESULT(mDataManager->MutableDatabaseManagerPtr()->GetFile(
aRequest.entryId(), type, lastModifiedMilliSeconds, path, file)), aRequest.entryId(), type, lastModifiedMilliSeconds, path, file)),
IPC_OK(), reportError); resolveAndReturn);
if (LOG_ENABLED()) { if (LOG_ENABLED()) {
nsAutoString path; nsAutoString path;
@ -152,7 +151,7 @@ mozilla::ipc::IPCResult FileSystemManagerParent::RecvGetAccessHandle(
mDataManager->OriginMetadataRef(), mDataManager->OriginMetadataRef(),
quota::Client::FILESYSTEM, file, -1, -1, quota::Client::FILESYSTEM, file, -1, -1,
nsIFileRandomAccessStream::DEFER_OPEN), nsIFileRandomAccessStream::DEFER_OPEN),
IPC_OK(), reportError); resolveAndReturn);
EnsureStreamCallbacks(); EnsureStreamCallbacks();
@ -161,13 +160,7 @@ mozilla::ipc::IPCResult FileSystemManagerParent::RecvGetAccessHandle(
WrapMovingNotNullUnchecked(std::move(stream)), mStreamCallbacks); WrapMovingNotNullUnchecked(std::move(stream)), mStreamCallbacks);
auto accessHandleParent = auto accessHandleParent =
MakeRefPtr<FileSystemAccessHandleParent>(this, aRequest.entryId()); MakeRefPtr<FileSystemAccessHandleParent>(accessHandle);
// Release the auto unlock helper just before calling
// SendPFileSystemAccessHandleConstructor which is responsible for destroying
// the actor if the sending fails (we call `UnlockExclusive` when the actor is
// destroyed).
autoUnlock.release();
if (!SendPFileSystemAccessHandleConstructor(accessHandleParent)) { if (!SendPFileSystemAccessHandleConstructor(accessHandleParent)) {
aResolver(NS_ERROR_FAILURE); aResolver(NS_ERROR_FAILURE);
@ -176,6 +169,7 @@ mozilla::ipc::IPCResult FileSystemManagerParent::RecvGetAccessHandle(
aResolver(FileSystemAccessHandleProperties(std::move(streamParams), aResolver(FileSystemAccessHandleProperties(std::move(streamParams),
accessHandleParent, nullptr)); accessHandleParent, nullptr));
return IPC_OK(); return IPC_OK();
} }

Просмотреть файл

@ -9,6 +9,7 @@ DIRS += [
] ]
EXPORTS.mozilla.dom += [ EXPORTS.mozilla.dom += [
"FileSystemAccessHandle.h",
"FileSystemAccessHandleParent.h", "FileSystemAccessHandleParent.h",
"FileSystemManagerParent.h", "FileSystemManagerParent.h",
"FileSystemManagerParentFactory.h", "FileSystemManagerParentFactory.h",
@ -17,6 +18,7 @@ EXPORTS.mozilla.dom += [
] ]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
"FileSystemAccessHandle.cpp",
"FileSystemAccessHandleParent.cpp", "FileSystemAccessHandleParent.cpp",
"FileSystemHashSource.cpp", "FileSystemHashSource.cpp",
"FileSystemManagerParent.cpp", "FileSystemManagerParent.cpp",