1 // Copyright 2013 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
5 #include "storage/browser/file_system/quota/quota_reservation.h"
6
7 #include <stdint.h>
8
9 #include <memory>
10
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "storage/browser/file_system/quota/open_file_handle.h"
14 #include "storage/browser/file_system/quota/quota_reservation_buffer.h"
15
16 namespace storage {
17
RefreshReservation(int64_t size,StatusCallback callback)18 void QuotaReservation::RefreshReservation(int64_t size,
19 StatusCallback callback) {
20 DCHECK(sequence_checker_.CalledOnValidSequence());
21 DCHECK(!running_refresh_request_);
22 DCHECK(!client_crashed_);
23 if (!reservation_manager())
24 return;
25
26 running_refresh_request_ = true;
27
28 reservation_manager()->ReserveQuota(
29 origin(), type(), size - remaining_quota_,
30 base::BindOnce(&QuotaReservation::AdaptDidUpdateReservedQuota,
31 weak_ptr_factory_.GetWeakPtr(), remaining_quota_,
32 std::move(callback)));
33
34 if (running_refresh_request_)
35 remaining_quota_ = 0;
36 }
37
GetOpenFileHandle(const base::FilePath & platform_path)38 std::unique_ptr<OpenFileHandle> QuotaReservation::GetOpenFileHandle(
39 const base::FilePath& platform_path) {
40 DCHECK(sequence_checker_.CalledOnValidSequence());
41 DCHECK(!client_crashed_);
42 return reservation_buffer_->GetOpenFileHandle(this, platform_path);
43 }
44
OnClientCrash()45 void QuotaReservation::OnClientCrash() {
46 DCHECK(sequence_checker_.CalledOnValidSequence());
47 client_crashed_ = true;
48
49 if (remaining_quota_) {
50 reservation_buffer_->PutReservationToBuffer(remaining_quota_);
51 remaining_quota_ = 0;
52 }
53 }
54
ConsumeReservation(int64_t size)55 void QuotaReservation::ConsumeReservation(int64_t size) {
56 DCHECK(sequence_checker_.CalledOnValidSequence());
57 DCHECK_LT(0, size);
58 DCHECK_LE(size, remaining_quota_);
59 if (client_crashed_)
60 return;
61
62 remaining_quota_ -= size;
63 reservation_buffer_->PutReservationToBuffer(size);
64 }
65
reservation_manager()66 QuotaReservationManager* QuotaReservation::reservation_manager() {
67 return reservation_buffer_->reservation_manager();
68 }
69
origin() const70 const url::Origin& QuotaReservation::origin() const {
71 return reservation_buffer_->origin();
72 }
73
type() const74 FileSystemType QuotaReservation::type() const {
75 return reservation_buffer_->type();
76 }
77
QuotaReservation(QuotaReservationBuffer * reservation_buffer)78 QuotaReservation::QuotaReservation(QuotaReservationBuffer* reservation_buffer)
79 : client_crashed_(false),
80 running_refresh_request_(false),
81 remaining_quota_(0),
82 reservation_buffer_(reservation_buffer) {
83 DCHECK(sequence_checker_.CalledOnValidSequence());
84 }
85
~QuotaReservation()86 QuotaReservation::~QuotaReservation() {
87 DCHECK(sequence_checker_.CalledOnValidSequence());
88
89 if (remaining_quota_ && reservation_manager()) {
90 reservation_manager()->ReleaseReservedQuota(origin(), type(),
91 remaining_quota_);
92 }
93 }
94
95 // static
AdaptDidUpdateReservedQuota(const base::WeakPtr<QuotaReservation> & reservation,int64_t previous_size,StatusCallback callback,base::File::Error error,int64_t delta)96 bool QuotaReservation::AdaptDidUpdateReservedQuota(
97 const base::WeakPtr<QuotaReservation>& reservation,
98 int64_t previous_size,
99 StatusCallback callback,
100 base::File::Error error,
101 int64_t delta) {
102 if (!reservation)
103 return false;
104
105 return reservation->DidUpdateReservedQuota(previous_size, std::move(callback),
106 error, delta);
107 }
108
DidUpdateReservedQuota(int64_t previous_size,StatusCallback callback,base::File::Error error,int64_t delta)109 bool QuotaReservation::DidUpdateReservedQuota(int64_t previous_size,
110 StatusCallback callback,
111 base::File::Error error,
112 int64_t delta) {
113 DCHECK(sequence_checker_.CalledOnValidSequence());
114 DCHECK(running_refresh_request_);
115 running_refresh_request_ = false;
116
117 if (client_crashed_) {
118 std::move(callback).Run(base::File::FILE_ERROR_ABORT);
119 return false;
120 }
121
122 if (error == base::File::FILE_OK)
123 remaining_quota_ = previous_size + delta;
124 std::move(callback).Run(error);
125 return true;
126 }
127
128 } // namespace storage
129