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

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

Issue 1846363002: [BlobAsync] Adding better error reporting and some new tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed switch statement Created 4 years, 8 months 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_async_builder_host.h" 5 #include "storage/browser/blob/blob_async_builder_host.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/memory/shared_memory.h" 13 #include "base/memory/shared_memory.h"
14 #include "storage/browser/blob/blob_data_handle.h" 14 #include "storage/browser/blob/blob_data_handle.h"
15 #include "storage/browser/blob/blob_storage_context.h" 15 #include "storage/browser/blob/blob_storage_context.h"
16 16
17 namespace storage { 17 namespace storage {
18 namespace { 18 namespace {
19
19 bool CalculateBlobMemorySize(const std::vector<DataElement>& elements, 20 bool CalculateBlobMemorySize(const std::vector<DataElement>& elements,
20 size_t* shortcut_bytes, 21 size_t* shortcut_bytes,
21 uint64_t* total_bytes) { 22 uint64_t* total_bytes) {
22 DCHECK(shortcut_bytes); 23 DCHECK(shortcut_bytes);
23 DCHECK(total_bytes); 24 DCHECK(total_bytes);
24 base::CheckedNumeric<uint64_t> total_size_checked = 0; 25 base::CheckedNumeric<uint64_t> total_size_checked = 0;
25 base::CheckedNumeric<size_t> shortcut_size_checked = 0; 26 base::CheckedNumeric<size_t> shortcut_size_checked = 0;
26 for (const auto& e : elements) { 27 for (const auto& e : elements) {
27 if (e.type() == DataElement::TYPE_BYTES) { 28 if (e.type() == DataElement::TYPE_BYTES) {
28 total_size_checked += e.length(); 29 total_size_checked += e.length();
29 shortcut_size_checked += e.length(); 30 shortcut_size_checked += e.length();
30 } else if (e.type() == DataElement::TYPE_BYTES_DESCRIPTION) { 31 } else if (e.type() == DataElement::TYPE_BYTES_DESCRIPTION) {
31 total_size_checked += e.length(); 32 total_size_checked += e.length();
32 } else { 33 } else {
33 continue; 34 continue;
34 } 35 }
35 if (!total_size_checked.IsValid() || !shortcut_size_checked.IsValid()) { 36 if (!total_size_checked.IsValid() || !shortcut_size_checked.IsValid()) {
36 return false; 37 return false;
37 } 38 }
38 } 39 }
39 *shortcut_bytes = shortcut_size_checked.ValueOrDie(); 40 *shortcut_bytes = shortcut_size_checked.ValueOrDie();
40 *total_bytes = total_size_checked.ValueOrDie(); 41 *total_bytes = total_size_checked.ValueOrDie();
41 return true; 42 return true;
42 } 43 }
44
45 IPCBlobCreationCancelCode TransformReferencedBlobErrorToConstructingError(
46 IPCBlobCreationCancelCode referenced_blob_error) {
47 switch (referenced_blob_error) {
48 // For most cases we propogate the error.
jsbell 2016/04/04 20:41:19 Typo: propagate
dmurph 2016/04/04 22:17:42 Done.
49 case IPCBlobCreationCancelCode::FILE_WRITE_FAILED:
50 case IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT:
51 case IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN:
52 case IPCBlobCreationCancelCode::OUT_OF_MEMORY:
53 return referenced_blob_error;
54 // Others we report that the referenced blob is broken, as we don't know
55 // why (the BLOB_DEREFERENCED_WHILE_BUILDING should never happen, as we hold
jsbell 2016/04/04 20:41:19 Do we want to DCHECK so we'd notice this during de
dmurph 2016/04/04 22:17:42 Done.
56 // onto the reference of the blobs we're using).
57 case IPCBlobCreationCancelCode::UNKNOWN:
58 case IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING:
59 return IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN;
60 }
61 NOTREACHED();
62 }
63
43 } // namespace 64 } // namespace
44 65
45 using MemoryItemRequest = 66 using MemoryItemRequest =
46 BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest; 67 BlobAsyncTransportRequestBuilder::RendererMemoryItemRequest;
47 68
48 BlobAsyncBuilderHost::BlobBuildingState::BlobBuildingState( 69 BlobAsyncBuilderHost::BlobBuildingState::BlobBuildingState(
49 const std::string& uuid, 70 const std::string& uuid,
50 std::set<std::string> referenced_blob_uuids, 71 std::set<std::string> referenced_blob_uuids,
51 std::vector<scoped_ptr<BlobDataHandle>>* referenced_blob_handles) 72 std::vector<scoped_ptr<BlobDataHandle>>* referenced_blob_handles)
52 : data_builder(uuid), 73 : data_builder(uuid),
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 // 'built'. In this case, it's destructed in the context, but we still have 297 // 'built'. In this case, it's destructed in the context, but we still have
277 // it in our map. Hence we make sure the context has the entry before 298 // it in our map. Hence we make sure the context has the entry before
278 // calling cancel. 299 // calling cancel.
279 if (context->registry().HasEntry(uuid)) 300 if (context->registry().HasEntry(uuid))
280 context->CancelPendingBlob(uuid, code); 301 context->CancelPendingBlob(uuid, code);
281 async_blob_map_.erase(state_it); 302 async_blob_map_.erase(state_it);
282 } 303 }
283 304
284 void BlobAsyncBuilderHost::CancelAll(BlobStorageContext* context) { 305 void BlobAsyncBuilderHost::CancelAll(BlobStorageContext* context) {
285 DCHECK(context); 306 DCHECK(context);
286 // Some of our pending blobs may still be referenced elsewhere. 307 // If the blob still exists in the context (and is being built), then we know
308 // that someone else is expecting our blob, and we need to cancel it to let
309 // the dependency know it's gone.
287 std::vector<scoped_ptr<BlobDataHandle>> referenced_pending_blobs; 310 std::vector<scoped_ptr<BlobDataHandle>> referenced_pending_blobs;
288 for (const auto& uuid_state_pair : async_blob_map_) { 311 for (const auto& uuid_state_pair : async_blob_map_) {
289 if (context->IsBeingBuilt(uuid_state_pair.first)) { 312 if (context->IsBeingBuilt(uuid_state_pair.first)) {
290 referenced_pending_blobs.emplace_back( 313 referenced_pending_blobs.emplace_back(
291 context->GetBlobDataFromUUID(uuid_state_pair.first)); 314 context->GetBlobDataFromUUID(uuid_state_pair.first));
292 } 315 }
293 } 316 }
294 // We clear the map before canceling them to prevent any strange reentry into 317 // We clear the map before canceling them to prevent any strange reentry into
295 // our class (see ReferencedBlobFinished) if any blobs were waiting for others 318 // our class (see ReferencedBlobFinished) if any blobs were waiting for others
296 // to construct. 319 // to construct.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 400
378 state->request_memory_callback.Run( 401 state->request_memory_callback.Run(
379 std::move(byte_requests), std::move(shared_memory), 402 std::move(byte_requests), std::move(shared_memory),
380 make_scoped_ptr(new std::vector<base::File>())); 403 make_scoped_ptr(new std::vector<base::File>()));
381 return BlobTransportResult::PENDING_RESPONSES; 404 return BlobTransportResult::PENDING_RESPONSES;
382 } 405 }
383 406
384 void BlobAsyncBuilderHost::ReferencedBlobFinished( 407 void BlobAsyncBuilderHost::ReferencedBlobFinished(
385 const std::string& owning_blob_uuid, 408 const std::string& owning_blob_uuid,
386 base::WeakPtr<BlobStorageContext> context, 409 base::WeakPtr<BlobStorageContext> context,
387 bool construction_success) { 410 bool construction_success,
411 IPCBlobCreationCancelCode reason) {
jsbell 2016/04/04 20:41:19 ISTM we should combine these, e.g. ResultCode w/ O
dmurph 2016/04/04 22:17:42 YES this is definitely better. However, this would
388 if (!context) { 412 if (!context) {
389 return; 413 return;
390 } 414 }
391 auto state_it = async_blob_map_.find(owning_blob_uuid); 415 auto state_it = async_blob_map_.find(owning_blob_uuid);
392 if (state_it == async_blob_map_.end()) { 416 if (state_it == async_blob_map_.end()) {
393 return; 417 return;
394 } 418 }
395 if (!construction_success) { 419 if (!construction_success) {
396 CancelBuildingBlob(owning_blob_uuid, 420 CancelBuildingBlob(owning_blob_uuid,
397 IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, 421 TransformReferencedBlobErrorToConstructingError(reason),
398 context.get()); 422 context.get());
399 return; 423 return;
400 } 424 }
401 BlobBuildingState* state = state_it->second.get(); 425 BlobBuildingState* state = state_it->second.get();
402 DCHECK_GT(state->num_referenced_blobs_building, 0u); 426 DCHECK_GT(state->num_referenced_blobs_building, 0u);
403 if (--state->num_referenced_blobs_building == 0) { 427 if (--state->num_referenced_blobs_building == 0) {
404 context->CompletePendingBlob(state->data_builder); 428 context->CompletePendingBlob(state->data_builder);
405 async_blob_map_.erase(state->data_builder.uuid()); 429 async_blob_map_.erase(state->data_builder.uuid());
406 } 430 }
407 } 431 }
(...skipping 20 matching lines...) Expand all
428 if (state->num_referenced_blobs_building > 0) { 452 if (state->num_referenced_blobs_building > 0) {
429 // We wait until referenced blobs are done. 453 // We wait until referenced blobs are done.
430 return; 454 return;
431 } 455 }
432 } 456 }
433 context->CompletePendingBlob(state->data_builder); 457 context->CompletePendingBlob(state->data_builder);
434 async_blob_map_.erase(state->data_builder.uuid()); 458 async_blob_map_.erase(state->data_builder.uuid());
435 } 459 }
436 460
437 } // namespace storage 461 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698