Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: storage/browser/blob/blob_storage_context.cc

Issue 2550113003: Revert of [BlobStorage] Implementing disk. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "storage/browser/blob/blob_storage_context.h" 5 #include "storage/browser/blob/blob_storage_context.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <memory> 9 #include <memory>
10 #include <set> 10 #include <set>
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 BlobStorageContext::BlobFlattener::BlobFlattener( 85 BlobStorageContext::BlobFlattener::BlobFlattener(
86 const BlobDataBuilder& input_builder, 86 const BlobDataBuilder& input_builder,
87 BlobEntry* output_blob, 87 BlobEntry* output_blob,
88 BlobStorageRegistry* registry) { 88 BlobStorageRegistry* registry) {
89 const std::string& uuid = input_builder.uuid_; 89 const std::string& uuid = input_builder.uuid_;
90 std::set<std::string> dependent_blob_uuids; 90 std::set<std::string> dependent_blob_uuids;
91 91
92 size_t num_files_with_unknown_size = 0; 92 size_t num_files_with_unknown_size = 0;
93 size_t num_building_dependent_blobs = 0; 93 size_t num_building_dependent_blobs = 0;
94 94
95 bool found_memory_transport = false;
96 bool found_file_transport = false;
97
98 base::CheckedNumeric<uint64_t> checked_total_size = 0; 95 base::CheckedNumeric<uint64_t> checked_total_size = 0;
99 base::CheckedNumeric<uint64_t> checked_total_memory_size = 0; 96 base::CheckedNumeric<uint64_t> checked_total_memory_size = 0;
100 base::CheckedNumeric<uint64_t> checked_transport_quota_needed = 0; 97 base::CheckedNumeric<uint64_t> checked_memory_quota_needed = 0;
101 base::CheckedNumeric<uint64_t> checked_copy_quota_needed = 0;
102 98
103 for (scoped_refptr<BlobDataItem> input_item : input_builder.items_) { 99 for (scoped_refptr<BlobDataItem> input_item : input_builder.items_) {
104 const DataElement& input_element = input_item->data_element(); 100 const DataElement& input_element = input_item->data_element();
105 DataElement::Type type = input_element.type(); 101 DataElement::Type type = input_element.type();
106 uint64_t length = input_element.length(); 102 uint64_t length = input_element.length();
107 103
108 RecordBlobItemSizeStats(input_element); 104 RecordBlobItemSizeStats(input_element);
109 105
110 if (IsBytes(type)) { 106 if (IsBytes(type)) {
111 DCHECK_NE(0 + DataElement::kUnknownSize, input_element.length()); 107 DCHECK_NE(0 + DataElement::kUnknownSize, input_element.length());
112 found_memory_transport = true; 108 checked_memory_quota_needed += length;
113 if (found_file_transport) {
114 // We cannot have both memory and file transport items.
115 status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
116 return;
117 }
118 contains_unpopulated_transport_items |=
119 (type == DataElement::TYPE_BYTES_DESCRIPTION);
120 checked_transport_quota_needed += length;
121 checked_total_size += length; 109 checked_total_size += length;
122 scoped_refptr<ShareableBlobDataItem> item = new ShareableBlobDataItem( 110 scoped_refptr<ShareableBlobDataItem> item = new ShareableBlobDataItem(
123 std::move(input_item), ShareableBlobDataItem::QUOTA_NEEDED); 111 std::move(input_item), ShareableBlobDataItem::QUOTA_NEEDED);
124 pending_transport_items.push_back(item); 112 pending_memory_items.push_back(item);
125 transport_items.push_back(item.get()); 113 transport_items.push_back(item.get());
126 output_blob->AppendSharedBlobItem(std::move(item)); 114 output_blob->AppendSharedBlobItem(std::move(item));
127 continue; 115 continue;
128 } 116 }
129 if (type == DataElement::TYPE_BLOB) { 117 if (type == DataElement::TYPE_BLOB) {
130 BlobEntry* ref_entry = registry->GetEntry(input_element.blob_uuid()); 118 BlobEntry* ref_entry = registry->GetEntry(input_element.blob_uuid());
131 119
132 if (!ref_entry || input_element.blob_uuid() == uuid) { 120 if (!ref_entry || input_element.blob_uuid() == uuid) {
133 status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; 121 status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
134 return; 122 return;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 !slice.total_memory_size.IsValid()) { 167 !slice.total_memory_size.IsValid()) {
180 status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; 168 status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
181 return; 169 return;
182 } 170 }
183 checked_total_memory_size += slice.total_memory_size; 171 checked_total_memory_size += slice.total_memory_size;
184 172
185 if (slice.first_source_item) { 173 if (slice.first_source_item) {
186 copies.push_back(ItemCopyEntry(slice.first_source_item, 174 copies.push_back(ItemCopyEntry(slice.first_source_item,
187 slice.first_item_slice_offset, 175 slice.first_item_slice_offset,
188 slice.dest_items.front())); 176 slice.dest_items.front()));
189 pending_copy_items.push_back(slice.dest_items.front()); 177 pending_memory_items.push_back(slice.dest_items.front());
190 } 178 }
191 if (slice.last_source_item) { 179 if (slice.last_source_item) {
192 copies.push_back( 180 copies.push_back(
193 ItemCopyEntry(slice.last_source_item, 0, slice.dest_items.back())); 181 ItemCopyEntry(slice.last_source_item, 0, slice.dest_items.back()));
194 pending_copy_items.push_back(slice.dest_items.back()); 182 pending_memory_items.push_back(slice.dest_items.back());
195 } 183 }
196 checked_copy_quota_needed += slice.copying_memory_size; 184 checked_memory_quota_needed += slice.copying_memory_size;
197 185
198 for (auto& shareable_item : slice.dest_items) { 186 for (auto& shareable_item : slice.dest_items) {
199 output_blob->AppendSharedBlobItem(std::move(shareable_item)); 187 output_blob->AppendSharedBlobItem(std::move(shareable_item));
200 } 188 }
201 continue; 189 continue;
202 } 190 }
203 191
204 // If the source item is a temporary file item, then we need to keep track 192 DCHECK(!BlobDataBuilder::IsFutureFileItem(input_element))
205 // of that and mark it as needing quota. 193 << "File allocation not implemented.";
206 scoped_refptr<ShareableBlobDataItem> item;
207 if (BlobDataBuilder::IsFutureFileItem(input_element)) {
208 found_file_transport = true;
209 if (found_memory_transport) {
210 // We cannot have both memory and file transport items.
211 status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
212 return;
213 }
214 contains_unpopulated_transport_items = true;
215 item = new ShareableBlobDataItem(std::move(input_item),
216 ShareableBlobDataItem::QUOTA_NEEDED);
217 pending_transport_items.push_back(item);
218 transport_items.push_back(item.get());
219 checked_transport_quota_needed += length;
220 } else {
221 item = new ShareableBlobDataItem(
222 std::move(input_item),
223 ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA);
224 }
225 if (length == DataElement::kUnknownSize) 194 if (length == DataElement::kUnknownSize)
226 num_files_with_unknown_size++; 195 num_files_with_unknown_size++;
227 196
197 scoped_refptr<ShareableBlobDataItem> item = new ShareableBlobDataItem(
198 std::move(input_item), ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA);
199
228 checked_total_size += length; 200 checked_total_size += length;
229 output_blob->AppendSharedBlobItem(std::move(item)); 201 output_blob->AppendSharedBlobItem(std::move(item));
230 } 202 }
231 203
232 if (num_files_with_unknown_size > 1 && input_builder.items_.size() > 1) { 204 if (num_files_with_unknown_size > 1 && input_builder.items_.size() > 1) {
233 status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; 205 status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
234 return; 206 return;
235 } 207 }
236 if (!checked_total_size.IsValid() || !checked_total_memory_size.IsValid() || 208 if (!checked_total_size.IsValid() || !checked_total_memory_size.IsValid() ||
237 !checked_transport_quota_needed.IsValid() || 209 !checked_memory_quota_needed.IsValid()) {
238 !checked_copy_quota_needed.IsValid()) {
239 status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; 210 status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
240 return; 211 return;
241 } 212 }
242 total_size = checked_total_size.ValueOrDie(); 213 total_size = checked_total_size.ValueOrDie();
243 total_memory_size = checked_total_memory_size.ValueOrDie(); 214 total_memory_size = checked_total_memory_size.ValueOrDie();
244 transport_quota_needed = checked_transport_quota_needed.ValueOrDie(); 215 memory_quota_needed = checked_memory_quota_needed.ValueOrDie();
245 copy_quota_needed = checked_copy_quota_needed.ValueOrDie(); 216 if (memory_quota_needed) {
246 transport_quota_type = found_file_transport ? TransportQuotaType::FILE
247 : TransportQuotaType::MEMORY;
248 if (transport_quota_needed) {
249 status = BlobStatus::PENDING_QUOTA; 217 status = BlobStatus::PENDING_QUOTA;
250 } else { 218 } else {
251 status = BlobStatus::PENDING_INTERNALS; 219 status = BlobStatus::PENDING_INTERNALS;
252 } 220 }
253 } 221 }
254 222
255 BlobStorageContext::BlobFlattener::~BlobFlattener() {} 223 BlobStorageContext::BlobFlattener::~BlobFlattener() {}
256 224
257 BlobStorageContext::BlobSlice::BlobSlice(const BlobEntry& source, 225 BlobStorageContext::BlobSlice::BlobSlice(const BlobEntry& source,
258 uint64_t slice_offset, 226 uint64_t slice_offset,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 case DataElement::TYPE_FILE: { 291 case DataElement::TYPE_FILE: {
324 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.File", 292 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.File",
325 read_size / 1024); 293 read_size / 1024);
326 std::unique_ptr<DataElement> element(new DataElement()); 294 std::unique_ptr<DataElement> element(new DataElement());
327 element->SetToFilePathRange( 295 element->SetToFilePathRange(
328 source_item->path(), source_item->offset() + item_offset, read_size, 296 source_item->path(), source_item->offset() + item_offset, read_size,
329 source_item->expected_modification_time()); 297 source_item->expected_modification_time());
330 data_item = 298 data_item =
331 new BlobDataItem(std::move(element), source_item->data_handle_); 299 new BlobDataItem(std::move(element), source_item->data_handle_);
332 300
333 if (BlobDataBuilder::IsFutureFileItem(source_item->data_element())) { 301 DCHECK(!BlobDataBuilder::IsFutureFileItem(source_item->data_element()))
334 // The source file isn't a real file yet (path is fake), so store the 302 << "File allocation unimplemented.";
335 // items we need to copy from later.
336 if (item_index == first_item_index) {
337 first_item_slice_offset = item_offset;
338 first_source_item = source_items[item_index];
339 } else {
340 last_source_item = source_items[item_index];
341 }
342 }
343 break; 303 break;
344 } 304 }
345 case DataElement::TYPE_FILE_FILESYSTEM: { 305 case DataElement::TYPE_FILE_FILESYSTEM: {
346 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.FileSystem", 306 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.FileSystem",
347 read_size / 1024); 307 read_size / 1024);
348 std::unique_ptr<DataElement> element(new DataElement()); 308 std::unique_ptr<DataElement> element(new DataElement());
349 element->SetToFileSystemUrlRange( 309 element->SetToFileSystemUrlRange(
350 source_item->filesystem_url(), source_item->offset() + item_offset, 310 source_item->filesystem_url(), source_item->offset() + item_offset,
351 read_size, source_item->expected_modification_time()); 311 read_size, source_item->expected_modification_time());
352 data_item = new BlobDataItem(std::move(element)); 312 data_item = new BlobDataItem(std::move(element));
(...skipping 21 matching lines...) Expand all
374 item_offset = 0; 334 item_offset = 0;
375 } 335 }
376 } 336 }
377 337
378 BlobStorageContext::BlobSlice::~BlobSlice() {} 338 BlobStorageContext::BlobSlice::~BlobSlice() {}
379 339
380 BlobStorageContext::BlobStorageContext() 340 BlobStorageContext::BlobStorageContext()
381 : memory_controller_(base::FilePath(), scoped_refptr<base::TaskRunner>()), 341 : memory_controller_(base::FilePath(), scoped_refptr<base::TaskRunner>()),
382 ptr_factory_(this) {} 342 ptr_factory_(this) {}
383 343
384 BlobStorageContext::BlobStorageContext( 344 BlobStorageContext::~BlobStorageContext() {
385 base::FilePath storage_directory, 345 }
386 scoped_refptr<base::TaskRunner> file_runner)
387 : memory_controller_(std::move(storage_directory), std::move(file_runner)),
388 ptr_factory_(this) {}
389
390 BlobStorageContext::~BlobStorageContext() {}
391 346
392 std::unique_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID( 347 std::unique_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID(
393 const std::string& uuid) { 348 const std::string& uuid) {
394 BlobEntry* entry = registry_.GetEntry(uuid); 349 BlobEntry* entry = registry_.GetEntry(uuid);
395 if (!entry) 350 if (!entry)
396 return nullptr; 351 return nullptr;
397 return CreateHandle(uuid, entry); 352 return CreateHandle(uuid, entry);
398 } 353 }
399 354
400 std::unique_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL( 355 std::unique_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 const TransportAllowedCallback& transport_allowed_callback) { 407 const TransportAllowedCallback& transport_allowed_callback) {
453 DCHECK(!registry_.HasEntry(content.uuid_)); 408 DCHECK(!registry_.HasEntry(content.uuid_));
454 409
455 BlobEntry* entry = registry_.CreateEntry( 410 BlobEntry* entry = registry_.CreateEntry(
456 content.uuid(), content.content_type_, content.content_disposition_); 411 content.uuid(), content.content_type_, content.content_disposition_);
457 412
458 // This flattens all blob references in the transportion content out and 413 // This flattens all blob references in the transportion content out and
459 // stores the complete item representation in the internal data. 414 // stores the complete item representation in the internal data.
460 BlobFlattener flattener(content, entry, &registry_); 415 BlobFlattener flattener(content, entry, &registry_);
461 416
462 DCHECK(!flattener.contains_unpopulated_transport_items || 417 DCHECK(flattener.status != BlobStatus::PENDING_TRANSPORT ||
418 !transport_allowed_callback)
419 << "There is no pending content for the user to populate, so the "
420 "callback should be null.";
421 DCHECK(flattener.status != BlobStatus::PENDING_TRANSPORT ||
463 transport_allowed_callback) 422 transport_allowed_callback)
464 << "If we have pending unpopulated content then a callback is required"; 423 << "If we have pending content then there needs to be a callback "
424 "present.";
465 425
466 entry->set_size(flattener.total_size); 426 entry->set_size(flattener.total_size);
467 entry->set_status(flattener.status); 427 entry->set_status(flattener.status);
468 std::unique_ptr<BlobDataHandle> handle = CreateHandle(content.uuid_, entry); 428 std::unique_ptr<BlobDataHandle> handle = CreateHandle(content.uuid_, entry);
469 429
470 UMA_HISTOGRAM_COUNTS("Storage.Blob.ItemCount", entry->items().size()); 430 UMA_HISTOGRAM_COUNTS("Storage.Blob.ItemCount", entry->items().size());
471 UMA_HISTOGRAM_COUNTS("Storage.Blob.TotalSize", 431 UMA_HISTOGRAM_COUNTS("Storage.Blob.TotalSize",
472 flattener.total_memory_size / 1024); 432 flattener.total_memory_size / 1024);
473
474 uint64_t total_memory_needed =
475 flattener.copy_quota_needed +
476 (flattener.transport_quota_type == TransportQuotaType::MEMORY
477 ? flattener.transport_quota_needed
478 : 0);
479 UMA_HISTOGRAM_COUNTS("Storage.Blob.TotalUnsharedSize", 433 UMA_HISTOGRAM_COUNTS("Storage.Blob.TotalUnsharedSize",
480 total_memory_needed / 1024); 434 flattener.memory_quota_needed / 1024);
481 435
482 size_t num_building_dependent_blobs = 0; 436 size_t num_building_dependent_blobs = 0;
483 std::vector<std::unique_ptr<BlobDataHandle>> dependent_blobs; 437 std::vector<std::unique_ptr<BlobDataHandle>> dependent_blobs;
484 // We hold a handle to all blobs we're using. This is important, as our memory 438 // We hold a handle to all blobs we're using. This is important, as our memory
485 // accounting can be delayed until OnEnoughSizeForBlobData is called, and we 439 // accounting can be delayed until OnEnoughSizeForBlobData is called, and we
486 // only free memory on canceling when we've done this accounting. If a 440 // only free memory on canceling when we've done this accounting. If a
487 // dependent blob is dereferenced, then we're the last blob holding onto that 441 // dependent blob is dereferenced, then we're the last blob holding onto that
488 // data item, and we need to account for that. So we prevent that case by 442 // data item, and we need to account for that. So we prevent that case by
489 // holding onto all blobs. 443 // holding onto all blobs.
490 for (const std::pair<std::string, BlobEntry*>& pending_blob : 444 for (const std::pair<std::string, BlobEntry*>& pending_blob :
491 flattener.dependent_blobs) { 445 flattener.dependent_blobs) {
492 dependent_blobs.push_back( 446 dependent_blobs.push_back(
493 CreateHandle(pending_blob.first, pending_blob.second)); 447 CreateHandle(pending_blob.first, pending_blob.second));
494 if (BlobStatusIsPending(pending_blob.second->status())) { 448 if (BlobStatusIsPending(pending_blob.second->status())) {
495 pending_blob.second->building_state_->build_completion_callbacks 449 pending_blob.second->building_state_->build_completion_callbacks
496 .push_back(base::Bind(&BlobStorageContext::OnDependentBlobFinished, 450 .push_back(base::Bind(&BlobStorageContext::OnDependentBlobFinished,
497 ptr_factory_.GetWeakPtr(), content.uuid_)); 451 ptr_factory_.GetWeakPtr(), content.uuid_));
498 num_building_dependent_blobs++; 452 num_building_dependent_blobs++;
499 } 453 }
500 } 454 }
501 455
502 entry->set_building_state(base::MakeUnique<BlobEntry::BuildingState>( 456 entry->set_building_state(base::MakeUnique<BlobEntry::BuildingState>(
503 !flattener.pending_transport_items.empty(), transport_allowed_callback, 457 !flattener.transport_items.empty(), transport_allowed_callback,
504 num_building_dependent_blobs)); 458 num_building_dependent_blobs));
505 BlobEntry::BuildingState* building_state = entry->building_state_.get(); 459 BlobEntry::BuildingState* building_state = entry->building_state_.get();
506 std::swap(building_state->copies, flattener.copies); 460 std::swap(building_state->copies, flattener.copies);
507 std::swap(building_state->dependent_blobs, dependent_blobs); 461 std::swap(building_state->dependent_blobs, dependent_blobs);
508 std::swap(building_state->transport_items, flattener.transport_items); 462 std::swap(building_state->transport_items, flattener.transport_items);
509 463
510 // Break ourselves if we have an error. BuildingState must be set first so the 464 // Break ourselves if we have an error. BuildingState must be set first so the
511 // callback is called correctly. 465 // callback is called correctly.
512 if (BlobStatusIsError(flattener.status)) { 466 if (BlobStatusIsError(flattener.status)) {
513 CancelBuildingBlobInternal(entry, flattener.status); 467 CancelBuildingBlobInternal(entry, flattener.status);
514 return handle; 468 return handle;
515 } 469 }
516 470
517 // Avoid the state where we might grant only one quota. 471 if (!memory_controller_.CanReserveQuota(flattener.memory_quota_needed)) {
518 if (!memory_controller_.CanReserveQuota(flattener.copy_quota_needed +
519 flattener.transport_quota_needed)) {
520 CancelBuildingBlobInternal(entry, BlobStatus::ERR_OUT_OF_MEMORY); 472 CancelBuildingBlobInternal(entry, BlobStatus::ERR_OUT_OF_MEMORY);
521 return handle; 473 return handle;
522 } 474 }
523 475
524 if (flattener.copy_quota_needed > 0) { 476 if (flattener.memory_quota_needed > 0) {
525 // The blob can complete during the execution of |ReserveMemoryQuota|. 477 // The blob can complete during the execution of this line.
526 base::WeakPtr<QuotaAllocationTask> pending_request = 478 base::WeakPtr<QuotaAllocationTask> pending_request =
527 memory_controller_.ReserveMemoryQuota( 479 memory_controller_.ReserveMemoryQuota(
528 std::move(flattener.pending_copy_items), 480 std::move(flattener.pending_memory_items),
529 base::Bind(&BlobStorageContext::OnEnoughSpaceForCopies, 481 base::Bind(&BlobStorageContext::OnEnoughSizeForMemory,
530 ptr_factory_.GetWeakPtr(), content.uuid_)); 482 ptr_factory_.GetWeakPtr(), content.uuid_));
531 // Building state will be null if the blob is already finished. 483 // Building state will be null if the blob is already finished.
532 if (entry->building_state_) 484 if (entry->building_state_)
533 entry->building_state_->copy_quota_request = std::move(pending_request); 485 entry->building_state_->memory_quota_request = std::move(pending_request);
534 }
535
536 if (flattener.transport_quota_needed > 0) {
537 base::WeakPtr<QuotaAllocationTask> pending_request;
538
539 switch (flattener.transport_quota_type) {
540 case TransportQuotaType::MEMORY: {
541 // The blob can complete during the execution of |ReserveMemoryQuota|.
542 std::vector<BlobMemoryController::FileCreationInfo> empty_files;
543 pending_request = memory_controller_.ReserveMemoryQuota(
544 std::move(flattener.pending_transport_items),
545 base::Bind(&BlobStorageContext::OnEnoughSpaceForTransport,
546 ptr_factory_.GetWeakPtr(), content.uuid_,
547 base::Passed(&empty_files)));
548 break;
549 }
550 case TransportQuotaType::FILE:
551 pending_request = memory_controller_.ReserveFileQuota(
552 std::move(flattener.pending_transport_items),
553 base::Bind(&BlobStorageContext::OnEnoughSpaceForTransport,
554 ptr_factory_.GetWeakPtr(), content.uuid_));
555 break;
556 }
557
558 // Building state will be null if the blob is already finished.
559 if (entry->building_state_) {
560 entry->building_state_->transport_quota_request =
561 std::move(pending_request);
562 }
563 } 486 }
564 487
565 if (entry->CanFinishBuilding()) 488 if (entry->CanFinishBuilding())
566 FinishBuilding(entry); 489 FinishBuilding(entry);
567 490
568 return handle; 491 return handle;
569 } 492 }
570 493
571 void BlobStorageContext::CancelBuildingBlob(const std::string& uuid, 494 void BlobStorageContext::CancelBuildingBlob(const std::string& uuid,
572 BlobStatus reason) { 495 BlobStatus reason) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 // Our source item can be a file if it was a slice of an unpopulated file, 615 // Our source item can be a file if it was a slice of an unpopulated file,
693 // or a slice of data that was then paged to disk. 616 // or a slice of data that was then paged to disk.
694 size_t dest_size = static_cast<size_t>(copy.dest_item->item()->length()); 617 size_t dest_size = static_cast<size_t>(copy.dest_item->item()->length());
695 DataElement::Type dest_type = copy.dest_item->item()->type(); 618 DataElement::Type dest_type = copy.dest_item->item()->type();
696 switch (copy.source_item->item()->type()) { 619 switch (copy.source_item->item()->type()) {
697 case DataElement::TYPE_BYTES: { 620 case DataElement::TYPE_BYTES: {
698 DCHECK_EQ(dest_type, DataElement::TYPE_BYTES_DESCRIPTION); 621 DCHECK_EQ(dest_type, DataElement::TYPE_BYTES_DESCRIPTION);
699 const char* src_data = 622 const char* src_data =
700 copy.source_item->item()->bytes() + copy.source_item_offset; 623 copy.source_item->item()->bytes() + copy.source_item_offset;
701 copy.dest_item->item()->item_->SetToBytes(src_data, dest_size); 624 copy.dest_item->item()->item_->SetToBytes(src_data, dest_size);
702 break; 625 } break;
703 } 626 case DataElement::TYPE_FILE:
704 case DataElement::TYPE_FILE: {
705 // If we expected a memory item (and our source was paged to disk) we
706 // free that memory.
707 if (dest_type == DataElement::TYPE_BYTES_DESCRIPTION)
708 copy.dest_item->set_memory_allocation(nullptr);
709
710 const DataElement& source_element =
711 copy.source_item->item()->data_element();
712 std::unique_ptr<DataElement> new_element(new DataElement());
713 new_element->SetToFilePathRange(
714 source_element.path(),
715 source_element.offset() + copy.source_item_offset, dest_size,
716 source_element.expected_modification_time());
717 scoped_refptr<BlobDataItem> new_item(new BlobDataItem(
718 std::move(new_element), copy.source_item->item()->data_handle_));
719 copy.dest_item->set_item(std::move(new_item));
720 break;
721 }
722 case DataElement::TYPE_UNKNOWN: 627 case DataElement::TYPE_UNKNOWN:
723 case DataElement::TYPE_BLOB: 628 case DataElement::TYPE_BLOB:
724 case DataElement::TYPE_BYTES_DESCRIPTION: 629 case DataElement::TYPE_BYTES_DESCRIPTION:
725 case DataElement::TYPE_FILE_FILESYSTEM: 630 case DataElement::TYPE_FILE_FILESYSTEM:
726 case DataElement::TYPE_DISK_CACHE_ENTRY: 631 case DataElement::TYPE_DISK_CACHE_ENTRY:
727 NOTREACHED(); 632 NOTREACHED();
728 break; 633 break;
729 } 634 }
730 copy.dest_item->set_state(ShareableBlobDataItem::POPULATED_WITH_QUOTA); 635 copy.dest_item->set_state(ShareableBlobDataItem::POPULATED_WITH_QUOTA);
731 } 636 }
(...skipping 26 matching lines...) Expand all
758 BlobEntry::BuildingState* building_state = entry->building_state_.get(); 663 BlobEntry::BuildingState* building_state = entry->building_state_.get();
759 if (building_state->transport_allowed_callback) { 664 if (building_state->transport_allowed_callback) {
760 base::ResetAndReturn(&building_state->transport_allowed_callback) 665 base::ResetAndReturn(&building_state->transport_allowed_callback)
761 .Run(BlobStatus::PENDING_TRANSPORT, std::move(files)); 666 .Run(BlobStatus::PENDING_TRANSPORT, std::move(files));
762 return; 667 return;
763 } 668 }
764 DCHECK(files.empty()); 669 DCHECK(files.empty());
765 NotifyTransportCompleteInternal(entry); 670 NotifyTransportCompleteInternal(entry);
766 } 671 }
767 672
768 void BlobStorageContext::OnEnoughSpaceForTransport( 673 void BlobStorageContext::OnEnoughSizeForMemory(const std::string& uuid,
769 const std::string& uuid, 674 bool success) {
770 std::vector<BlobMemoryController::FileCreationInfo> files,
771 bool success) {
772 if (!success) { 675 if (!success) {
773 CancelBuildingBlob(uuid, BlobStatus::ERR_OUT_OF_MEMORY); 676 CancelBuildingBlob(uuid, BlobStatus::ERR_OUT_OF_MEMORY);
774 return; 677 return;
775 } 678 }
776 BlobEntry* entry = registry_.GetEntry(uuid); 679 BlobEntry* entry = registry_.GetEntry(uuid);
777 if (!entry || !entry->building_state_.get()) 680 if (!entry || !entry->building_state_.get())
778 return; 681 return;
779 BlobEntry::BuildingState& building_state = *entry->building_state_; 682 BlobEntry::BuildingState& building_state = *entry->building_state_;
780 DCHECK(!building_state.transport_quota_request); 683 DCHECK(!building_state.memory_quota_request);
781 DCHECK(building_state.transport_items_present);
782 684
783 entry->set_status(BlobStatus::PENDING_TRANSPORT); 685 if (building_state.transport_items_present) {
784 RequestTransport(entry, std::move(files)); 686 entry->set_status(BlobStatus::PENDING_TRANSPORT);
687 RequestTransport(entry,
688 std::vector<BlobMemoryController::FileCreationInfo>());
689 } else {
690 entry->set_status(BlobStatus::PENDING_INTERNALS);
691 }
785 692
786 if (entry->CanFinishBuilding()) 693 if (entry->CanFinishBuilding())
787 FinishBuilding(entry); 694 FinishBuilding(entry);
788 }
789
790 void BlobStorageContext::OnEnoughSpaceForCopies(const std::string& uuid,
791 bool success) {
792 if (!success) {
793 CancelBuildingBlob(uuid, BlobStatus::ERR_OUT_OF_MEMORY);
794 return;
795 }
796 BlobEntry* entry = registry_.GetEntry(uuid);
797 if (!entry)
798 return;
799
800 if (entry->CanFinishBuilding())
801 FinishBuilding(entry);
802 } 695 }
803 696
804 void BlobStorageContext::OnDependentBlobFinished( 697 void BlobStorageContext::OnDependentBlobFinished(
805 const std::string& owning_blob_uuid, 698 const std::string& owning_blob_uuid,
806 BlobStatus status) { 699 BlobStatus status) {
807 BlobEntry* entry = registry_.GetEntry(owning_blob_uuid); 700 BlobEntry* entry = registry_.GetEntry(owning_blob_uuid);
808 if (!entry || !entry->building_state_) 701 if (!entry || !entry->building_state_)
809 return; 702 return;
810 703
811 if (BlobStatusIsError(status)) { 704 if (BlobStatusIsError(status)) {
812 DCHECK_NE(BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING, status) 705 DCHECK_NE(BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING, status)
813 << "Referenced blob should never be dereferenced while we " 706 << "Referenced blob should never be dereferenced while we "
814 << "are depending on it, as our system holds a handle."; 707 << "are depending on it, as our system holds a handle.";
815 CancelBuildingBlobInternal(entry, BlobStatus::ERR_REFERENCED_BLOB_BROKEN); 708 CancelBuildingBlobInternal(entry, BlobStatus::ERR_REFERENCED_BLOB_BROKEN);
816 return; 709 return;
817 } 710 }
818 DCHECK_GT(entry->building_state_->num_building_dependent_blobs, 0u); 711 DCHECK_GT(entry->building_state_->num_building_dependent_blobs, 0u);
819 --entry->building_state_->num_building_dependent_blobs; 712 --entry->building_state_->num_building_dependent_blobs;
820 713
821 if (entry->CanFinishBuilding()) 714 if (entry->CanFinishBuilding())
822 FinishBuilding(entry); 715 FinishBuilding(entry);
823 } 716 }
824 717
825 void BlobStorageContext::ClearAndFreeMemory(BlobEntry* entry) { 718 void BlobStorageContext::ClearAndFreeMemory(BlobEntry* entry) {
826 if (entry->building_state_) 719 if (entry->building_state_) {
827 entry->building_state_->CancelRequests(); 720 BlobEntry::BuildingState* building_state = entry->building_state_.get();
721 if (building_state->memory_quota_request) {
722 building_state->memory_quota_request->Cancel();
723 }
724 }
828 entry->ClearItems(); 725 entry->ClearItems();
829 entry->ClearOffsets(); 726 entry->ClearOffsets();
830 entry->set_size(0); 727 entry->set_size(0);
831 } 728 }
832 729
833 } // namespace storage 730 } // namespace storage
OLDNEW
« no previous file with comments | « storage/browser/blob/blob_storage_context.h ('k') | storage/common/blob_storage/blob_storage_constants.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698