diff options
author | Cronet Mainline Eng <cronet-mainline-eng+copybara@google.com> | 2023-03-20 09:24:50 -0800 |
---|---|---|
committer | Patrick Rohr <prohr@google.com> | 2023-03-20 10:25:51 -0700 |
commit | 14c9064f78517fd0e9366547030c0493aa075b47 (patch) | |
tree | 6e03046ec4055bb9881ff0341716266b5d53782b /net/disk_cache/backend_cleanup_tracker.cc | |
parent | d1add53d6e90815f363c91d433735556ce79b0d2 (diff) | |
download | cronet-14c9064f78517fd0e9366547030c0493aa075b47.tar.gz |
Import Cronet version 108.0.5359.128
Project import generated by Copybara.
FolderOrigin-RevId: /tmp/copybara-origin/src
Test: none
Change-Id: I98ebcd5784650764c7cd70ab175dd4e1cc790dff
Diffstat (limited to 'net/disk_cache/backend_cleanup_tracker.cc')
-rw-r--r-- | net/disk_cache/backend_cleanup_tracker.cc | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/net/disk_cache/backend_cleanup_tracker.cc b/net/disk_cache/backend_cleanup_tracker.cc new file mode 100644 index 000000000..ff685bb9c --- /dev/null +++ b/net/disk_cache/backend_cleanup_tracker.cc @@ -0,0 +1,95 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Internal helper used to sequence cleanup and reuse of cache directories +// among different objects. + +#include "net/disk_cache/backend_cleanup_tracker.h" + +#include <unordered_map> +#include <utility> + +#include "base/callback.h" +#include "base/files/file_path.h" +#include "base/lazy_instance.h" +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "base/task/sequenced_task_runner.h" +#include "base/threading/sequenced_task_runner_handle.h" + +namespace disk_cache { + +namespace { + +using TrackerMap = std::unordered_map<base::FilePath, BackendCleanupTracker*>; +struct AllBackendCleanupTrackers { + TrackerMap map; + + // Since clients can potentially call CreateCacheBackend from multiple + // threads, we need to lock the map keeping track of cleanup trackers + // for these backends. Our overall strategy is to have TryCreate + // acts as an arbitrator --- whatever thread grabs one, gets to operate + // on the tracker freely until it gets destroyed. + base::Lock lock; +}; + +static base::LazyInstance<AllBackendCleanupTrackers>::Leaky g_all_trackers; + +} // namespace. + +// static +scoped_refptr<BackendCleanupTracker> BackendCleanupTracker::TryCreate( + const base::FilePath& path, + base::OnceClosure retry_closure) { + AllBackendCleanupTrackers* all_trackers = g_all_trackers.Pointer(); + base::AutoLock lock(all_trackers->lock); + + std::pair<TrackerMap::iterator, bool> insert_result = + all_trackers->map.insert( + std::pair<base::FilePath, BackendCleanupTracker*>(path, nullptr)); + if (insert_result.second) { + auto tracker = base::WrapRefCounted(new BackendCleanupTracker(path)); + insert_result.first->second = tracker.get(); + return tracker; + } else { + insert_result.first->second->AddPostCleanupCallbackImpl( + std::move(retry_closure)); + return nullptr; + } +} + +void BackendCleanupTracker::AddPostCleanupCallback(base::OnceClosure cb) { + DCHECK_CALLED_ON_VALID_SEQUENCE(seq_checker_); + // Despite the sequencing requirement we need to grab the table lock since + // this may otherwise race against TryMakeContext. + base::AutoLock lock(g_all_trackers.Get().lock); + AddPostCleanupCallbackImpl(std::move(cb)); +} + +void BackendCleanupTracker::AddPostCleanupCallbackImpl(base::OnceClosure cb) { + post_cleanup_cbs_.emplace_back(base::SequencedTaskRunnerHandle::Get(), + std::move(cb)); +} + +BackendCleanupTracker::BackendCleanupTracker(const base::FilePath& path) + : path_(path) {} + +BackendCleanupTracker::~BackendCleanupTracker() { + DCHECK_CALLED_ON_VALID_SEQUENCE(seq_checker_); + + { + AllBackendCleanupTrackers* all_trackers = g_all_trackers.Pointer(); + base::AutoLock lock(all_trackers->lock); + int rv = all_trackers->map.erase(path_); + DCHECK_EQ(1, rv); + } + + while (!post_cleanup_cbs_.empty()) { + post_cleanup_cbs_.back().first->PostTask( + FROM_HERE, std::move(post_cleanup_cbs_.back().second)); + post_cleanup_cbs_.pop_back(); + } +} + +} // namespace disk_cache |