From b4553921d06dad1e7ef3bb55fa62a88815412c6c Mon Sep 17 00:00:00 2001 From: Leonid Baraz Date: Tue, 12 Jul 2022 23:32:53 +0000 Subject: [PATCH] Enable new ScopedReservation to inherit another. Bug: b:233089187 Bug: b:237811834 Make it possible to create a new scoped reservation for the same resource interface as another one - useful when the latter is not available directly (this eliminates the need to propagate the interface to where it is needed). Also some clean-ups in the code/declarations. Change-Id: I0e7f9f4bdbef593eab7c52fbec018715e629839b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3754714 Reviewed-by: Hong Xu Commit-Queue: Hong Xu Auto-Submit: Leonid Baraz Cr-Commit-Position: refs/heads/main@{#1023479} --- .../reporting/resources/resource_interface.cc | 11 ++++++++++ .../reporting/resources/resource_interface.h | 4 ++++ .../resources/resource_interface_unittest.cc | 21 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/components/reporting/resources/resource_interface.cc b/components/reporting/resources/resource_interface.cc index df8141a95c8c7e..4e7d32fe88330a 100644 --- a/components/reporting/resources/resource_interface.cc +++ b/components/reporting/resources/resource_interface.cc @@ -27,6 +27,17 @@ ScopedReservation::ScopedReservation( size_ = size; } +ScopedReservation::ScopedReservation( + uint64_t size, + const ScopedReservation& other_reservation) noexcept + : resource_interface_(other_reservation.resource_interface_) { + if (size == 0uL || !resource_interface_.get() || + !resource_interface_->Reserve(size)) { + return; + } + size_ = size; +} + ScopedReservation::ScopedReservation(ScopedReservation&& other) noexcept : resource_interface_(other.resource_interface_), size_(std::exchange(other.size_, absl::nullopt)) {} diff --git a/components/reporting/resources/resource_interface.h b/components/reporting/resources/resource_interface.h index a3fb0fb600c93b..8f29c7222848dd 100644 --- a/components/reporting/resources/resource_interface.h +++ b/components/reporting/resources/resource_interface.h @@ -76,6 +76,10 @@ class ScopedReservation { ScopedReservation( uint64_t size, scoped_refptr resource_interface) noexcept; + // New reservation on the same resource interface as |other_reservation|. + ScopedReservation(uint64_t size, + const ScopedReservation& other_reservation) noexcept; + // Move constructor. ScopedReservation(ScopedReservation&& other) noexcept; ScopedReservation(const ScopedReservation& other) = delete; ScopedReservation& operator=(ScopedReservation&& other) = delete; diff --git a/components/reporting/resources/resource_interface_unittest.cc b/components/reporting/resources/resource_interface_unittest.cc index b77e4ecf834d1c..3d627f1c5b636b 100644 --- a/components/reporting/resources/resource_interface_unittest.cc +++ b/components/reporting/resources/resource_interface_unittest.cc @@ -188,6 +188,27 @@ TEST_P(ResourceInterfaceTest, ScopedReservationRepeatingHandOvers) { Eq(resource_interface()->GetTotal() - 1)); } +TEST_P(ResourceInterfaceTest, ScopedReservationRepeatingCopyHandOvers) { + uint64_t size = resource_interface()->GetTotal() / 2; + ScopedReservation scoped_reservation(size, resource_interface()); + EXPECT_TRUE(scoped_reservation.reserved()); + + for (; size >= 2; size /= 2) { + ScopedReservation another_reservation(size / 2, scoped_reservation); + EXPECT_TRUE(another_reservation.reserved()); + scoped_reservation.HandOver(another_reservation); + } + EXPECT_THAT(resource_interface()->GetUsed(), + Eq(resource_interface()->GetTotal() - 1)); +} + +TEST_P(ResourceInterfaceTest, ScopedReservationFailureToCopyFromEmpty) { + ScopedReservation scoped_reservation; + uint64_t size = resource_interface()->GetTotal() / 2; + ScopedReservation another_reservation(size, scoped_reservation); + EXPECT_FALSE(scoped_reservation.reserved()); +} + TEST_P(ResourceInterfaceTest, ScopedReservationRepeatingHandOversToEmpty) { ScopedReservation scoped_reservation; EXPECT_FALSE(scoped_reservation.reserved());