| OLD | NEW |
| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | |
| 10 #include <algorithm> | 9 #include <algorithm> |
| 11 #include <limits> | 10 #include <limits> |
| 11 #include <utility> |
| 12 | 12 |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/location.h" | 14 #include "base/location.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
| 17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 18 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
| 19 #include "base/thread_task_runner_handle.h" | 19 #include "base/thread_task_runner_handle.h" |
| 20 #include "base/trace_event/trace_event.h" | 20 #include "base/trace_event/trace_event.h" |
| 21 #include "storage/browser/blob/blob_data_builder.h" | 21 #include "storage/browser/blob/blob_data_builder.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 | 68 |
| 69 BlobStorageContext::~BlobStorageContext() { | 69 BlobStorageContext::~BlobStorageContext() { |
| 70 STLDeleteContainerPairSecondPointers(blob_map_.begin(), blob_map_.end()); | 70 STLDeleteContainerPairSecondPointers(blob_map_.begin(), blob_map_.end()); |
| 71 } | 71 } |
| 72 | 72 |
| 73 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID( | 73 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID( |
| 74 const std::string& uuid) { | 74 const std::string& uuid) { |
| 75 scoped_ptr<BlobDataHandle> result; | 75 scoped_ptr<BlobDataHandle> result; |
| 76 BlobMap::iterator found = blob_map_.find(uuid); | 76 BlobMap::iterator found = blob_map_.find(uuid); |
| 77 if (found == blob_map_.end()) | 77 if (found == blob_map_.end()) |
| 78 return result.Pass(); | 78 return result; |
| 79 auto* entry = found->second; | 79 auto* entry = found->second; |
| 80 if (entry->flags & EXCEEDED_MEMORY) | 80 if (entry->flags & EXCEEDED_MEMORY) |
| 81 return result.Pass(); | 81 return result; |
| 82 DCHECK(!entry->IsBeingBuilt()); | 82 DCHECK(!entry->IsBeingBuilt()); |
| 83 result.reset(new BlobDataHandle(uuid, entry->data->content_type(), | 83 result.reset(new BlobDataHandle(uuid, entry->data->content_type(), |
| 84 entry->data->content_disposition(), this, | 84 entry->data->content_disposition(), this, |
| 85 base::ThreadTaskRunnerHandle::Get().get())); | 85 base::ThreadTaskRunnerHandle::Get().get())); |
| 86 return result.Pass(); | 86 return result; |
| 87 } | 87 } |
| 88 | 88 |
| 89 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL( | 89 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL( |
| 90 const GURL& url) { | 90 const GURL& url) { |
| 91 BlobURLMap::iterator found = | 91 BlobURLMap::iterator found = |
| 92 public_blob_urls_.find(BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url); | 92 public_blob_urls_.find(BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url); |
| 93 if (found == public_blob_urls_.end()) | 93 if (found == public_blob_urls_.end()) |
| 94 return scoped_ptr<BlobDataHandle>(); | 94 return scoped_ptr<BlobDataHandle>(); |
| 95 return GetBlobDataFromUUID(found->second); | 95 return GetBlobDataFromUUID(found->second); |
| 96 } | 96 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 112 target_blob_builder)) { | 112 target_blob_builder)) { |
| 113 BlobEntryExceededMemory(entry); | 113 BlobEntryExceededMemory(entry); |
| 114 break; | 114 break; |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 | 117 |
| 118 FinishBuildingBlob(external_builder.uuid_, external_builder.content_type_); | 118 FinishBuildingBlob(external_builder.uuid_, external_builder.content_type_); |
| 119 scoped_ptr<BlobDataHandle> handle = | 119 scoped_ptr<BlobDataHandle> handle = |
| 120 GetBlobDataFromUUID(external_builder.uuid_); | 120 GetBlobDataFromUUID(external_builder.uuid_); |
| 121 DecrementBlobRefCount(external_builder.uuid_); | 121 DecrementBlobRefCount(external_builder.uuid_); |
| 122 return handle.Pass(); | 122 return handle; |
| 123 } | 123 } |
| 124 | 124 |
| 125 scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( | 125 scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( |
| 126 const BlobDataBuilder* builder) { | 126 const BlobDataBuilder* builder) { |
| 127 DCHECK(builder); | 127 DCHECK(builder); |
| 128 return AddFinishedBlob(*builder); | 128 return AddFinishedBlob(*builder); |
| 129 } | 129 } |
| 130 | 130 |
| 131 bool BlobStorageContext::RegisterPublicBlobURL(const GURL& blob_url, | 131 bool BlobStorageContext::RegisterPublicBlobURL(const GURL& blob_url, |
| 132 const std::string& uuid) { | 132 const std::string& uuid) { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 const std::string& uuid, | 266 const std::string& uuid, |
| 267 const DataElement& ipc_data) { | 267 const DataElement& ipc_data) { |
| 268 scoped_refptr<BlobDataItem> blob_item; | 268 scoped_refptr<BlobDataItem> blob_item; |
| 269 | 269 |
| 270 uint64_t length = ipc_data.length(); | 270 uint64_t length = ipc_data.length(); |
| 271 scoped_ptr<DataElement> element(new DataElement()); | 271 scoped_ptr<DataElement> element(new DataElement()); |
| 272 switch (ipc_data.type()) { | 272 switch (ipc_data.type()) { |
| 273 case DataElement::TYPE_BYTES: | 273 case DataElement::TYPE_BYTES: |
| 274 DCHECK(!ipc_data.offset()); | 274 DCHECK(!ipc_data.offset()); |
| 275 element->SetToBytes(ipc_data.bytes(), length); | 275 element->SetToBytes(ipc_data.bytes(), length); |
| 276 blob_item = new BlobDataItem(element.Pass()); | 276 blob_item = new BlobDataItem(std::move(element)); |
| 277 break; | 277 break; |
| 278 case DataElement::TYPE_FILE: | 278 case DataElement::TYPE_FILE: |
| 279 element->SetToFilePathRange(ipc_data.path(), ipc_data.offset(), length, | 279 element->SetToFilePathRange(ipc_data.path(), ipc_data.offset(), length, |
| 280 ipc_data.expected_modification_time()); | 280 ipc_data.expected_modification_time()); |
| 281 blob_item = new BlobDataItem( | 281 blob_item = new BlobDataItem( |
| 282 element.Pass(), ShareableFileReference::Get(ipc_data.path())); | 282 std::move(element), ShareableFileReference::Get(ipc_data.path())); |
| 283 break; | 283 break; |
| 284 case DataElement::TYPE_FILE_FILESYSTEM: | 284 case DataElement::TYPE_FILE_FILESYSTEM: |
| 285 element->SetToFileSystemUrlRange(ipc_data.filesystem_url(), | 285 element->SetToFileSystemUrlRange(ipc_data.filesystem_url(), |
| 286 ipc_data.offset(), length, | 286 ipc_data.offset(), length, |
| 287 ipc_data.expected_modification_time()); | 287 ipc_data.expected_modification_time()); |
| 288 blob_item = new BlobDataItem(element.Pass()); | 288 blob_item = new BlobDataItem(std::move(element)); |
| 289 break; | 289 break; |
| 290 case DataElement::TYPE_BLOB: | 290 case DataElement::TYPE_BLOB: |
| 291 // This is a temporary item that will be deconstructed later. | 291 // This is a temporary item that will be deconstructed later. |
| 292 element->SetToBlobRange(ipc_data.blob_uuid(), ipc_data.offset(), | 292 element->SetToBlobRange(ipc_data.blob_uuid(), ipc_data.offset(), |
| 293 ipc_data.length()); | 293 ipc_data.length()); |
| 294 blob_item = new BlobDataItem(element.Pass()); | 294 blob_item = new BlobDataItem(std::move(element)); |
| 295 break; | 295 break; |
| 296 case DataElement::TYPE_DISK_CACHE_ENTRY: // This type can't be sent by IPC. | 296 case DataElement::TYPE_DISK_CACHE_ENTRY: // This type can't be sent by IPC. |
| 297 NOTREACHED(); | 297 NOTREACHED(); |
| 298 break; | 298 break; |
| 299 default: | 299 default: |
| 300 NOTREACHED(); | 300 NOTREACHED(); |
| 301 break; | 301 break; |
| 302 } | 302 } |
| 303 | 303 |
| 304 return blob_item; | 304 return blob_item; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 new_length / 1024); | 440 new_length / 1024); |
| 441 if (memory_usage_ + new_length > kMaxMemoryUsage) { | 441 if (memory_usage_ + new_length > kMaxMemoryUsage) { |
| 442 return false; | 442 return false; |
| 443 } | 443 } |
| 444 DCHECK(!item.offset()); | 444 DCHECK(!item.offset()); |
| 445 scoped_ptr<DataElement> element(new DataElement()); | 445 scoped_ptr<DataElement> element(new DataElement()); |
| 446 element->SetToBytes(item.bytes() + offset, | 446 element->SetToBytes(item.bytes() + offset, |
| 447 static_cast<int64_t>(new_length)); | 447 static_cast<int64_t>(new_length)); |
| 448 memory_usage_ += new_length; | 448 memory_usage_ += new_length; |
| 449 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( | 449 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 450 target_blob_uuid, new BlobDataItem(element.Pass()))); | 450 target_blob_uuid, new BlobDataItem(std::move(element)))); |
| 451 } break; | 451 } break; |
| 452 case DataElement::TYPE_FILE: { | 452 case DataElement::TYPE_FILE: { |
| 453 DCHECK_NE(item.length(), std::numeric_limits<uint64_t>::max()) | 453 DCHECK_NE(item.length(), std::numeric_limits<uint64_t>::max()) |
| 454 << "We cannot use a section of a file with an unknown length"; | 454 << "We cannot use a section of a file with an unknown length"; |
| 455 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.File", | 455 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.File", |
| 456 new_length / 1024); | 456 new_length / 1024); |
| 457 scoped_ptr<DataElement> element(new DataElement()); | 457 scoped_ptr<DataElement> element(new DataElement()); |
| 458 element->SetToFilePathRange(item.path(), item.offset() + offset, | 458 element->SetToFilePathRange(item.path(), item.offset() + offset, |
| 459 new_length, | 459 new_length, |
| 460 item.expected_modification_time()); | 460 item.expected_modification_time()); |
| 461 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( | 461 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 462 target_blob_uuid, | 462 target_blob_uuid, |
| 463 new BlobDataItem(element.Pass(), item.data_handle_))); | 463 new BlobDataItem(std::move(element), item.data_handle_))); |
| 464 } break; | 464 } break; |
| 465 case DataElement::TYPE_FILE_FILESYSTEM: { | 465 case DataElement::TYPE_FILE_FILESYSTEM: { |
| 466 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.FileSystem", | 466 UMA_HISTOGRAM_COUNTS("Storage.BlobItemSize.BlobSlice.FileSystem", |
| 467 new_length / 1024); | 467 new_length / 1024); |
| 468 scoped_ptr<DataElement> element(new DataElement()); | 468 scoped_ptr<DataElement> element(new DataElement()); |
| 469 element->SetToFileSystemUrlRange(item.filesystem_url(), | 469 element->SetToFileSystemUrlRange(item.filesystem_url(), |
| 470 item.offset() + offset, new_length, | 470 item.offset() + offset, new_length, |
| 471 item.expected_modification_time()); | 471 item.expected_modification_time()); |
| 472 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( | 472 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 473 target_blob_uuid, new BlobDataItem(element.Pass()))); | 473 target_blob_uuid, new BlobDataItem(std::move(element)))); |
| 474 } break; | 474 } break; |
| 475 case DataElement::TYPE_DISK_CACHE_ENTRY: { | 475 case DataElement::TYPE_DISK_CACHE_ENTRY: { |
| 476 scoped_ptr<DataElement> element(new DataElement()); | 476 scoped_ptr<DataElement> element(new DataElement()); |
| 477 element->SetToDiskCacheEntryRange(item.offset() + offset, | 477 element->SetToDiskCacheEntryRange(item.offset() + offset, |
| 478 new_length); | 478 new_length); |
| 479 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( | 479 target_blob_builder->AppendSharedBlobItem(new ShareableBlobDataItem( |
| 480 target_blob_uuid, | 480 target_blob_uuid, |
| 481 new BlobDataItem(element.Pass(), item.data_handle_, | 481 new BlobDataItem(std::move(element), item.data_handle_, |
| 482 item.disk_cache_entry(), | 482 item.disk_cache_entry(), |
| 483 item.disk_cache_stream_index()))); | 483 item.disk_cache_stream_index()))); |
| 484 } break; | 484 } break; |
| 485 default: | 485 default: |
| 486 CHECK(false) << "Illegal blob item type: " << item.type(); | 486 CHECK(false) << "Illegal blob item type: " << item.type(); |
| 487 } | 487 } |
| 488 length -= new_length; | 488 length -= new_length; |
| 489 offset = 0; | 489 offset = 0; |
| 490 } | 490 } |
| 491 return true; | 491 return true; |
| 492 } | 492 } |
| 493 | 493 |
| 494 bool BlobStorageContext::IsInUse(const std::string& uuid) { | 494 bool BlobStorageContext::IsInUse(const std::string& uuid) { |
| 495 return blob_map_.find(uuid) != blob_map_.end(); | 495 return blob_map_.find(uuid) != blob_map_.end(); |
| 496 } | 496 } |
| 497 | 497 |
| 498 bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) { | 498 bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) { |
| 499 BlobMap::iterator found = blob_map_.find(uuid); | 499 BlobMap::iterator found = blob_map_.find(uuid); |
| 500 if (found == blob_map_.end()) | 500 if (found == blob_map_.end()) |
| 501 return false; | 501 return false; |
| 502 return found->second->IsBeingBuilt(); | 502 return found->second->IsBeingBuilt(); |
| 503 } | 503 } |
| 504 | 504 |
| 505 bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) { | 505 bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) { |
| 506 return public_blob_urls_.find(blob_url) != public_blob_urls_.end(); | 506 return public_blob_urls_.find(blob_url) != public_blob_urls_.end(); |
| 507 } | 507 } |
| 508 | 508 |
| 509 } // namespace storage | 509 } // namespace storage |
| OLD | NEW |