/* -*- 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_DATAMODEL_FILESYSTEMDATAMANAGER_H_ #define DOM_FS_PARENT_DATAMODEL_FILESYSTEMDATAMANAGER_H_ #include "ResultConnection.h" #include "mozilla/NotNull.h" #include "mozilla/TaskQueue.h" #include "mozilla/ThreadBound.h" #include "mozilla/dom/FileSystemHelpers.h" #include "mozilla/dom/FileSystemTypes.h" #include "mozilla/dom/quota/CheckedUnsafePtr.h" #include "mozilla/dom/quota/CommonMetadata.h" #include "mozilla/dom/quota/ForwardDecls.h" #include "nsCOMPtr.h" #include "nsISupportsUtils.h" #include "nsString.h" #include "nsTHashSet.h" namespace mozilla { template class Result; namespace dom { class FileSystemManagerParent; namespace fs { class FileSystemChildMetadata; } // namespace fs namespace quota { class DirectoryLock; } // namespace quota namespace fs::data { class FileSystemDatabaseManager; Result GetRootHandle(const Origin& origin); Result GetEntryHandle( const FileSystemChildMetadata& aHandle); class FileSystemDataManager : public SupportsCheckedUnsafePtr> { public: enum struct State : uint8_t { Initial = 0, Opening, Open, Closing, Closed }; FileSystemDataManager(const quota::OriginMetadata& aOriginMetadata, MovingNotNull> aIOTarget, MovingNotNull> aIOTaskQueue); // IsExclusive is true because we want to allow the move operations. There's // always just one consumer anyway. using CreatePromise = MozPromise, nsresult, /* IsExclusive */ true>; static RefPtr GetOrCreateFileSystemDataManager( const quota::OriginMetadata& aOriginMetadata); static void AbortOperationsForLocks( const quota::Client::DirectoryLockIdTable& aDirectoryLockIds); static void InitiateShutdown(); static bool IsShutdownCompleted(); NS_INLINE_DECL_REFCOUNTING(FileSystemDataManager) void AssertIsOnIOTarget() const; const quota::OriginMetadata& OriginMetadataRef() const { return mOriginMetadata; } nsISerialEventTarget* MutableBackgroundTargetPtr() const { return mBackgroundTarget.get(); } nsISerialEventTarget* MutableIOTargetPtr() const { return mIOTaskQueue.get(); } Maybe MaybeDirectoryLockRef() const { return ToMaybeRef(mDirectoryLock.get()); } FileSystemDatabaseManager* MutableDatabaseManagerPtr() const { MOZ_ASSERT(mDatabaseManager); return mDatabaseManager.get(); } void Register(); void Unregister(); void RegisterActor(NotNull aActor); void UnregisterActor(NotNull aActor); bool IsOpen() const { return mState == State::Open; } RefPtr OnOpen(); RefPtr OnClose(); bool IsLocked(const EntryId& aEntryId) const; bool LockExclusive(const EntryId& aEntryId); void UnlockExclusive(const EntryId& aEntryId); bool LockShared(const EntryId& aEntryId); void UnlockShared(const EntryId& aEntryId); protected: virtual ~FileSystemDataManager(); bool IsInactive() const; bool IsOpening() const { return mState == State::Opening; } bool IsClosing() const { return mState == State::Closing; } void RequestAllowToClose(); RefPtr BeginOpen(); RefPtr BeginClose(); // Things touched on background thread only. struct BackgroundThreadAccessible { nsTHashSet mActors; }; ThreadBound mBackgroundThreadAccessible; const quota::OriginMetadata mOriginMetadata; nsTHashSet mExclusiveLocks; const NotNull> mBackgroundTarget; const NotNull> mIOTarget; const NotNull> mIOTaskQueue; RefPtr mDirectoryLock; UniquePtr mDatabaseManager; MozPromiseHolder mOpenPromiseHolder; MozPromiseHolder mClosePromiseHolder; uint32_t mRegCount; State mState; }; } // namespace fs::data } // namespace dom } // namespace mozilla #endif // DOM_FS_PARENT_DATAMODEL_FILESYSTEMDATAMANAGER_H_