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