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 "webkit/browser/fileapi/quota/quota_reservation_buffer.h" 6 7 #include "base/bind.h" 8 #include "webkit/browser/fileapi/quota/open_file_handle.h" 9 #include "webkit/browser/fileapi/quota/open_file_handle_context.h" 10 #include "webkit/browser/fileapi/quota/quota_reservation.h" 11 12 namespace fileapi { 13 14 QuotaReservationBuffer::QuotaReservationBuffer( 15 base::WeakPtr<QuotaReservationManager> reservation_manager, 16 const GURL& origin, 17 FileSystemType type) 18 : reservation_manager_(reservation_manager), 19 origin_(origin), 20 type_(type), 21 reserved_quota_(0) { 22 DCHECK(origin.is_valid()); 23 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 24 reservation_manager_->IncrementDirtyCount(origin, type); 25 } 26 27 scoped_refptr<QuotaReservation> QuotaReservationBuffer::CreateReservation() { 28 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 29 return make_scoped_refptr(new QuotaReservation(this)); 30 } 31 32 scoped_ptr<OpenFileHandle> QuotaReservationBuffer::GetOpenFileHandle( 33 QuotaReservation* reservation, 34 const base::FilePath& platform_path) { 35 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 36 OpenFileHandleContext** open_file = &open_files_[platform_path]; 37 if (!*open_file) 38 *open_file = new OpenFileHandleContext(platform_path, this); 39 return make_scoped_ptr(new OpenFileHandle(reservation, *open_file)); 40 } 41 42 void QuotaReservationBuffer::CommitFileGrowth(int64 quota_consumption, 43 int64 usage_delta) { 44 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 45 if (!reservation_manager_) 46 return; 47 reservation_manager_->CommitQuotaUsage(origin_, type_, usage_delta); 48 49 if (quota_consumption > 0) { 50 if (quota_consumption > reserved_quota_) { 51 LOG(ERROR) << "Detected over consumption of the storage quota beyond its" 52 << " reservation"; 53 quota_consumption = reserved_quota_; 54 } 55 56 reserved_quota_ -= quota_consumption; 57 reservation_manager_->ReleaseReservedQuota( 58 origin_, type_, quota_consumption); 59 } 60 } 61 62 void QuotaReservationBuffer::DetachOpenFileHandleContext( 63 OpenFileHandleContext* open_file) { 64 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 65 DCHECK_EQ(open_file, open_files_[open_file->platform_path()]); 66 open_files_.erase(open_file->platform_path()); 67 } 68 69 void QuotaReservationBuffer::PutReservationToBuffer(int64 reservation) { 70 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 71 DCHECK_LE(0, reservation); 72 reserved_quota_ += reservation; 73 } 74 75 QuotaReservationBuffer::~QuotaReservationBuffer() { 76 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 77 if (!reservation_manager_) 78 return; 79 80 DCHECK_LE(0, reserved_quota_); 81 if (reserved_quota_ && reservation_manager_) { 82 reservation_manager_->ReserveQuota( 83 origin_, type_, -reserved_quota_, 84 base::Bind(&QuotaReservationBuffer::DecrementDirtyCount, 85 reservation_manager_, origin_, type_)); 86 } 87 reservation_manager_->ReleaseReservationBuffer(this); 88 } 89 90 // static 91 bool QuotaReservationBuffer::DecrementDirtyCount( 92 base::WeakPtr<QuotaReservationManager> reservation_manager, 93 const GURL& origin, 94 FileSystemType type, 95 base::PlatformFileError error) { 96 DCHECK(origin.is_valid()); 97 if (error == base::PLATFORM_FILE_OK && reservation_manager) { 98 reservation_manager->DecrementDirtyCount(origin, type); 99 return true; 100 } 101 return false; 102 } 103 104 105 } // namespace fileapi 106