blob: 6d6930af0e6c99c58b36522eb21c80741eb4815d [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "storage/browser/fileapi/quota/quota_reservation_buffer.h"
#include <stdint.h>
#include <memory>
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "storage/browser/fileapi/quota/open_file_handle.h"
#include "storage/browser/fileapi/quota/open_file_handle_context.h"
#include "storage/browser/fileapi/quota/quota_reservation.h"
namespace storage {
QuotaReservationBuffer::QuotaReservationBuffer(
base::WeakPtr<QuotaReservationManager> reservation_manager,
const GURL& origin,
FileSystemType type)
: reservation_manager_(reservation_manager),
origin_(origin),
type_(type),
reserved_quota_(0) {
DCHECK(origin.is_valid());
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
reservation_manager_->IncrementDirtyCount(origin, type);
}
scoped_refptr<QuotaReservation> QuotaReservationBuffer::CreateReservation() {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
return make_scoped_refptr(new QuotaReservation(this));
}
std::unique_ptr<OpenFileHandle> QuotaReservationBuffer::GetOpenFileHandle(
QuotaReservation* reservation,
const base::FilePath& platform_path) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
OpenFileHandleContext** open_file = &open_files_[platform_path];
if (!*open_file)
*open_file = new OpenFileHandleContext(platform_path, this);
return base::WrapUnique(new OpenFileHandle(reservation, *open_file));
}
void QuotaReservationBuffer::CommitFileGrowth(
int64_t reserved_quota_consumption,
int64_t usage_delta) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
if (!reservation_manager_)
return;
reservation_manager_->CommitQuotaUsage(origin_, type_, usage_delta);
if (reserved_quota_consumption > 0) {
if (reserved_quota_consumption > reserved_quota_) {
LOG(ERROR) << "Detected over consumption of the storage quota beyond its"
<< " reservation";
reserved_quota_consumption = reserved_quota_;
}
reserved_quota_ -= reserved_quota_consumption;
reservation_manager_->ReleaseReservedQuota(
origin_, type_, reserved_quota_consumption);
}
}
void QuotaReservationBuffer::DetachOpenFileHandleContext(
OpenFileHandleContext* open_file) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK_EQ(open_file, open_files_[open_file->platform_path()]);
open_files_.erase(open_file->platform_path());
}
void QuotaReservationBuffer::PutReservationToBuffer(int64_t reservation) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
DCHECK_LE(0, reservation);
reserved_quota_ += reservation;
}
QuotaReservationBuffer::~QuotaReservationBuffer() {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
if (!reservation_manager_)
return;
DCHECK_LE(0, reserved_quota_);
if (reserved_quota_ && reservation_manager_) {
reservation_manager_->ReserveQuota(
origin_, type_, -reserved_quota_,
base::Bind(&QuotaReservationBuffer::DecrementDirtyCount,
reservation_manager_, origin_, type_));
}
reservation_manager_->ReleaseReservationBuffer(this);
}
// static
bool QuotaReservationBuffer::DecrementDirtyCount(
base::WeakPtr<QuotaReservationManager> reservation_manager,
const GURL& origin,
FileSystemType type,
base::File::Error error,
int64_t delta_unused) {
DCHECK(origin.is_valid());
if (error == base::File::FILE_OK && reservation_manager) {
reservation_manager->DecrementDirtyCount(origin, type);
return true;
}
return false;
}
} // namespace storage