chromium/content/browser/file_system_access/file_system_access_lock_manager.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/file_system_access/file_system_access_lock_manager.h"

#include <optional>

#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/memory/raw_ref.h"
#include "base/types/optional_ref.h"
#include "components/services/storage/public/cpp/buckets/bucket_locator.h"
#include "content/browser/file_system_access/features.h"
#include "content/public/browser/disallow_activation_reason.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/render_frame_host.h"
#include "storage/browser/file_system/file_system_url.h"
#include "storage/common/file_system/file_system_types.h"
#include "third_party/blink/public/common/features_generated.h"

namespace content {

LockHandle;
LockType;

// This class represents an active lock on the `path`. The lock is kept alive
// when there is some `LockHandle` to it. The lock is released when all its
// `LockHandle`s have been destroyed.
//
// Terminology:
//  - A "caller" is the caller of `FileSystemAccessLockManager` `TakeLock`
//    function that requested the `Lock`. A `Lock` can have multiple callers.
//  - A "subtree" is subtree of the whole `Lock` tree. The `Lock` tree can
//    contain zero or more subtrees. Subtrees have a root called a subroot. A
//    `Lock` is considered to be in some subtree if the it is the subroot of the
//    subtree or a descendant of the subroot. A subtree can be one of two types:
//    Evicting or Pending.
//
// A `Lock` can be in one of two states: Taken or Pending.
//  - A `Lock` is Taken if any of its `LockHandle`s have been given out to the
//    callers. A `Lock` becomes Taken when it has either been created without
//    contention or it was a Pending `Lock` that was promoted to Taken.
//  - A `Lock` is Pending if none of its `LockHandle`s have not been given out
//    to its callers. Before it is promoted to a Taken `Lock`, a Pending `Lock`
//    can only be destroyed if it is evicted. A Pending `Lock` is in a Pending
//    subtree. A `Lock` is a Pending subroot when it has been created through
//    the eviction of a Taken `Lock` that has yet to be evicted. A Pending
//    `Lock` is promoted to a Taken when that evicting Taken `Lock` has finished
//    eviction.
//
// A `Lock` may be evicted to allow for the creation of a new `Lock`. This can
// only happen when the original `Lock` is held only by pages in the BFCache and
// it is in contention with the new `Lock`. The new `Lock` is created as a
// Pending `Lock` and takes the place of the original `Lock`. What happens to
// the original `Lock` depends on its state.
//  - When a Taken `Lock` is evicted, it becomes an Evicting subroot, so it and
//    its descendants are an Evicting subtree.
//  - When a Pending `Lock` is evicted, it is immediately destroyed by
//    destroying all LockHandles to it. An evicted Pending `Lock` will never
//    have its `LockHandle`s given to the caller.
class Lock {};

class RootLock : public Lock {};

// static
FileSystemAccessLockManager::RootLocator
FileSystemAccessLockManager::RootLocator::FromFileSystemURL(
    const storage::FileSystemURL& url) {}

FileSystemAccessLockManager::RootLocator::RootLocator(
    const EntryPathType& type,
    const std::optional<storage::BucketLocator>& bucket_locator)
    :{}
FileSystemAccessLockManager::RootLocator::RootLocator(const RootLocator&) =
    default;
FileSystemAccessLockManager::RootLocator::~RootLocator() = default;

bool FileSystemAccessLockManager::RootLocator::operator<(
    const RootLocator& other) const {}

LockHandle::LockHandle(base::WeakPtr<Lock> lock,
                       scoped_refptr<LockHandle> parent_lock_handle,
                       const GlobalRenderFrameHostId& frame_id)
    :{}

LockHandle::~LockHandle() {}

FileSystemAccessLockManager::FileSystemAccessLockManager(
    base::PassKey<FileSystemAccessManagerImpl> /*pass_key*/)
    :{}

FileSystemAccessLockManager::~FileSystemAccessLockManager() = default;

bool FileSystemAccessLockManager::IsContentious(
    const storage::FileSystemURL& url,
    LockType lock_type) {}

void FileSystemAccessLockManager::TakeLock(
    const GlobalRenderFrameHostId& frame_id,
    const storage::FileSystemURL& url,
    LockType lock_type,
    TakeLockCallback callback) {}

void FileSystemAccessLockManager::ReleaseRoot(const RootLocator& root_locator) {}

RootLock* FileSystemAccessLockManager::GetRootLock(
    const RootLocator& root_locator) {}

RootLock* FileSystemAccessLockManager::GetOrCreateRootLock(
    const RootLocator& root_locator) {}

FileSystemAccessLockManager::LockType
FileSystemAccessLockManager::CreateSharedLockType() {}

FileSystemAccessLockManager::LockType
FileSystemAccessLockManager::GetExclusiveLockType() {}

FileSystemAccessLockManager::LockType
FileSystemAccessLockManager::GetAncestorLockTypeForTesting() {}

base::WeakPtr<FileSystemAccessLockManager>
FileSystemAccessLockManager::GetWeakPtrForTesting() {}

}  // namespace content