resource_interface.cc 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/reporting/resources/resource_interface.h"
  5. #include <utility>
  6. #include <cstdint>
  7. #include "base/logging.h"
  8. #include "base/memory/ref_counted.h"
  9. #include "base/memory/scoped_refptr.h"
  10. #include "third_party/abseil-cpp/absl/types/optional.h"
  11. namespace reporting {
  12. ScopedReservation::ScopedReservation() noexcept = default;
  13. ScopedReservation::ScopedReservation(
  14. uint64_t size,
  15. scoped_refptr<ResourceInterface> resource_interface) noexcept
  16. : resource_interface_(resource_interface) {
  17. if (size == 0uL || !resource_interface->Reserve(size)) {
  18. return;
  19. }
  20. size_ = size;
  21. }
  22. ScopedReservation::ScopedReservation(
  23. uint64_t size,
  24. const ScopedReservation& other_reservation) noexcept
  25. : resource_interface_(other_reservation.resource_interface_) {
  26. if (size == 0uL || !resource_interface_.get() ||
  27. !resource_interface_->Reserve(size)) {
  28. return;
  29. }
  30. size_ = size;
  31. }
  32. ScopedReservation::ScopedReservation(ScopedReservation&& other) noexcept
  33. : resource_interface_(other.resource_interface_),
  34. size_(std::exchange(other.size_, absl::nullopt)) {}
  35. bool ScopedReservation::reserved() const {
  36. return size_.has_value();
  37. }
  38. bool ScopedReservation::Reduce(uint64_t new_size) {
  39. if (!reserved()) {
  40. return false;
  41. }
  42. if (new_size < 0 || size_.value() < new_size) {
  43. return false;
  44. }
  45. resource_interface_->Discard(size_.value() - new_size);
  46. if (new_size > 0) {
  47. size_ = new_size;
  48. } else {
  49. size_ = absl::nullopt;
  50. }
  51. return true;
  52. }
  53. void ScopedReservation::HandOver(ScopedReservation& other) {
  54. if (resource_interface_.get()) {
  55. DCHECK_EQ(resource_interface_.get(), other.resource_interface_.get())
  56. << "Reservations are not related";
  57. } else {
  58. DCHECK(!reserved()) << "Unattached reservation may not have size";
  59. resource_interface_ = other.resource_interface_;
  60. }
  61. if (!other.reserved()) {
  62. return; // Nothing changes.
  63. }
  64. const uint64_t old_size = (reserved() ? size_.value() : 0uL);
  65. size_ = old_size + std::exchange(other.size_, absl::nullopt).value();
  66. }
  67. ScopedReservation::~ScopedReservation() {
  68. if (reserved()) {
  69. resource_interface_->Discard(size_.value());
  70. }
  71. }
  72. } // namespace reporting