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

Side by Side Diff: net/disk_cache/sparse_control.cc

Issue 9702059: Disk cache: Remove all non essential synchronization from the cache destructor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "net/disk_cache/sparse_control.h" 5 #include "net/disk_cache/sparse_control.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/format_macros.h" 8 #include "base/format_macros.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 bool SparseControl::CouldBeSparse() const { 223 bool SparseControl::CouldBeSparse() const {
224 DCHECK(!init_); 224 DCHECK(!init_);
225 225
226 if (entry_->GetDataSize(kSparseData)) 226 if (entry_->GetDataSize(kSparseData))
227 return false; 227 return false;
228 228
229 // We don't verify the data, just see if it could be there. 229 // We don't verify the data, just see if it could be there.
230 return (entry_->GetDataSize(kSparseIndex) != 0); 230 return (entry_->GetDataSize(kSparseIndex) != 0);
231 } 231 }
232 232
233 int SparseControl::StartIO( 233 int SparseControl::StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
234 SparseOperation op, int64 offset, net::IOBuffer* buf, int buf_len, 234 int buf_len, const CompletionCallback& callback) {
235 const net::CompletionCallback& callback) {
236 DCHECK(init_); 235 DCHECK(init_);
237 // We don't support simultaneous IO for sparse data. 236 // We don't support simultaneous IO for sparse data.
238 if (operation_ != kNoOperation) 237 if (operation_ != kNoOperation)
239 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; 238 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
240 239
241 if (offset < 0 || buf_len < 0) 240 if (offset < 0 || buf_len < 0)
242 return net::ERR_INVALID_ARGUMENT; 241 return net::ERR_INVALID_ARGUMENT;
243 242
244 // We only support up to 64 GB. 243 // We only support up to 64 GB.
245 if (offset + buf_len >= 0x1000000000LL || offset + buf_len < 0) 244 if (offset + buf_len >= 0x1000000000LL || offset + buf_len < 0)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 int SparseControl::GetAvailableRange(int64 offset, int len, int64* start) { 283 int SparseControl::GetAvailableRange(int64 offset, int len, int64* start) {
285 DCHECK(init_); 284 DCHECK(init_);
286 // We don't support simultaneous IO for sparse data. 285 // We don't support simultaneous IO for sparse data.
287 if (operation_ != kNoOperation) 286 if (operation_ != kNoOperation)
288 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; 287 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
289 288
290 DCHECK(start); 289 DCHECK(start);
291 290
292 range_found_ = false; 291 range_found_ = false;
293 int result = StartIO( 292 int result = StartIO(
294 kGetRangeOperation, offset, NULL, len, net::CompletionCallback()); 293 kGetRangeOperation, offset, NULL, len, CompletionCallback());
295 if (range_found_) { 294 if (range_found_) {
296 *start = offset_; 295 *start = offset_;
297 return result; 296 return result;
298 } 297 }
299 298
300 // This is a failure. We want to return a valid start value in any case. 299 // This is a failure. We want to return a valid start value in any case.
301 *start = offset; 300 *start = offset;
302 return result < 0 ? result : 0; // Don't mask error codes to the caller. 301 return result < 0 ? result : 0; // Don't mask error codes to the caller.
303 } 302 }
304 303
305 void SparseControl::CancelIO() { 304 void SparseControl::CancelIO() {
306 if (operation_ == kNoOperation) 305 if (operation_ == kNoOperation)
307 return; 306 return;
308 abort_ = true; 307 abort_ = true;
309 } 308 }
310 309
311 int SparseControl::ReadyToUse(const net::CompletionCallback& callback) { 310 int SparseControl::ReadyToUse(const CompletionCallback& callback) {
312 if (!abort_) 311 if (!abort_)
313 return net::OK; 312 return net::OK;
314 313
315 // We'll grab another reference to keep this object alive because we just have 314 // We'll grab another reference to keep this object alive because we just have
316 // one extra reference due to the pending IO operation itself, but we'll 315 // one extra reference due to the pending IO operation itself, but we'll
317 // release that one before invoking user_callback_. 316 // release that one before invoking user_callback_.
318 entry_->AddRef(); // Balanced in DoAbortCallbacks. 317 entry_->AddRef(); // Balanced in DoAbortCallbacks.
319 abort_callbacks_.push_back(callback); 318 abort_callbacks_.push_back(callback);
320 return net::ERR_IO_PENDING; 319 return net::ERR_IO_PENDING;
321 } 320 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 sparse_header_.signature = Time::Now().ToInternalValue(); 363 sparse_header_.signature = Time::Now().ToInternalValue();
365 sparse_header_.magic = kIndexMagic; 364 sparse_header_.magic = kIndexMagic;
366 sparse_header_.parent_key_len = entry_->GetKey().size(); 365 sparse_header_.parent_key_len = entry_->GetKey().size();
367 children_map_.Resize(kNumSparseBits, true); 366 children_map_.Resize(kNumSparseBits, true);
368 367
369 // Save the header. The bitmap is saved in the destructor. 368 // Save the header. The bitmap is saved in the destructor.
370 scoped_refptr<net::IOBuffer> buf( 369 scoped_refptr<net::IOBuffer> buf(
371 new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_))); 370 new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_)));
372 371
373 int rv = entry_->WriteData( 372 int rv = entry_->WriteData(
374 kSparseIndex, 0, buf, sizeof(sparse_header_), net::CompletionCallback(), 373 kSparseIndex, 0, buf, sizeof(sparse_header_), CompletionCallback(),
375 false); 374 false);
376 if (rv != sizeof(sparse_header_)) { 375 if (rv != sizeof(sparse_header_)) {
377 DLOG(ERROR) << "Unable to save sparse_header_"; 376 DLOG(ERROR) << "Unable to save sparse_header_";
378 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; 377 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
379 } 378 }
380 379
381 entry_->SetEntryFlags(PARENT_ENTRY); 380 entry_->SetEntryFlags(PARENT_ENTRY);
382 return net::OK; 381 return net::OK;
383 } 382 }
384 383
(...skipping 11 matching lines...) Expand all
396 // Dont't go over board with the bitmap. 8 KB gives us offsets up to 64 GB. 395 // Dont't go over board with the bitmap. 8 KB gives us offsets up to 64 GB.
397 int map_len = data_len - sizeof(sparse_header_); 396 int map_len = data_len - sizeof(sparse_header_);
398 if (map_len > kMaxMapSize || map_len % 4) 397 if (map_len > kMaxMapSize || map_len % 4)
399 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; 398 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
400 399
401 scoped_refptr<net::IOBuffer> buf( 400 scoped_refptr<net::IOBuffer> buf(
402 new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_))); 401 new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_)));
403 402
404 // Read header. 403 // Read header.
405 int rv = entry_->ReadData( 404 int rv = entry_->ReadData(
406 kSparseIndex, 0, buf, sizeof(sparse_header_), net::CompletionCallback()); 405 kSparseIndex, 0, buf, sizeof(sparse_header_), CompletionCallback());
407 if (rv != static_cast<int>(sizeof(sparse_header_))) 406 if (rv != static_cast<int>(sizeof(sparse_header_)))
408 return net::ERR_CACHE_READ_FAILURE; 407 return net::ERR_CACHE_READ_FAILURE;
409 408
410 // The real validation should be performed by the caller. This is just to 409 // The real validation should be performed by the caller. This is just to
411 // double check. 410 // double check.
412 if (sparse_header_.magic != kIndexMagic || 411 if (sparse_header_.magic != kIndexMagic ||
413 sparse_header_.parent_key_len != 412 sparse_header_.parent_key_len !=
414 static_cast<int>(entry_->GetKey().size())) 413 static_cast<int>(entry_->GetKey().size()))
415 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; 414 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
416 415
417 // Read the actual bitmap. 416 // Read the actual bitmap.
418 buf = new net::IOBuffer(map_len); 417 buf = new net::IOBuffer(map_len);
419 rv = entry_->ReadData(kSparseIndex, sizeof(sparse_header_), buf, map_len, 418 rv = entry_->ReadData(kSparseIndex, sizeof(sparse_header_), buf, map_len,
420 net::CompletionCallback()); 419 CompletionCallback());
421 if (rv != map_len) 420 if (rv != map_len)
422 return net::ERR_CACHE_READ_FAILURE; 421 return net::ERR_CACHE_READ_FAILURE;
423 422
424 // Grow the bitmap to the current size and copy the bits. 423 // Grow the bitmap to the current size and copy the bits.
425 children_map_.Resize(map_len * 8, false); 424 children_map_.Resize(map_len * 8, false);
426 children_map_.SetMap(reinterpret_cast<uint32*>(buf->data()), map_len); 425 children_map_.SetMap(reinterpret_cast<uint32*>(buf->data()), map_len);
427 return net::OK; 426 return net::OK;
428 } 427 }
429 428
430 bool SparseControl::OpenChild() { 429 bool SparseControl::OpenChild() {
431 DCHECK_GE(result_, 0); 430 DCHECK_GE(result_, 0);
432 431
433 std::string key = GenerateChildKey(); 432 std::string key = GenerateChildKey();
434 if (child_) { 433 if (child_) {
435 // Keep using the same child or open another one?. 434 // Keep using the same child or open another one?.
436 if (key == child_->GetKey()) 435 if (key == child_->GetKey())
437 return true; 436 return true;
438 CloseChild(); 437 CloseChild();
439 } 438 }
440 439
441 // See if we are tracking this child. 440 // See if we are tracking this child.
442 if (!ChildPresent()) 441 if (!ChildPresent())
443 return ContinueWithoutChild(key); 442 return ContinueWithoutChild(key);
444 443
444 if (!entry_->backend_)
445 return false;
446
445 child_ = entry_->backend_->OpenEntryImpl(key); 447 child_ = entry_->backend_->OpenEntryImpl(key);
446 if (!child_) 448 if (!child_)
447 return ContinueWithoutChild(key); 449 return ContinueWithoutChild(key);
448 450
449 EntryImpl* child = static_cast<EntryImpl*>(child_); 451 EntryImpl* child = static_cast<EntryImpl*>(child_);
450 if (!(CHILD_ENTRY & child->GetEntryFlags()) || 452 if (!(CHILD_ENTRY & child->GetEntryFlags()) ||
451 child->GetDataSize(kSparseIndex) < 453 child->GetDataSize(kSparseIndex) <
452 static_cast<int>(sizeof(child_data_))) 454 static_cast<int>(sizeof(child_data_)))
453 return KillChildAndContinue(key, false); 455 return KillChildAndContinue(key, false);
454 456
455 scoped_refptr<net::WrappedIOBuffer> buf( 457 scoped_refptr<net::WrappedIOBuffer> buf(
456 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_))); 458 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_)));
457 459
458 // Read signature. 460 // Read signature.
459 int rv = child_->ReadData( 461 int rv = child_->ReadData(kSparseIndex, 0, buf, sizeof(child_data_),
460 kSparseIndex, 0, buf, sizeof(child_data_), net::CompletionCallback()); 462 CompletionCallback());
461 if (rv != sizeof(child_data_)) 463 if (rv != sizeof(child_data_))
462 return KillChildAndContinue(key, true); // This is a fatal failure. 464 return KillChildAndContinue(key, true); // This is a fatal failure.
463 465
464 if (child_data_.header.signature != sparse_header_.signature || 466 if (child_data_.header.signature != sparse_header_.signature ||
465 child_data_.header.magic != kIndexMagic) 467 child_data_.header.magic != kIndexMagic)
466 return KillChildAndContinue(key, false); 468 return KillChildAndContinue(key, false);
467 469
468 if (child_data_.header.last_block_len < 0 || 470 if (child_data_.header.last_block_len < 0 ||
469 child_data_.header.last_block_len > kBlockSize) { 471 child_data_.header.last_block_len > kBlockSize) {
470 // Make sure these values are always within range. 472 // Make sure these values are always within range.
471 child_data_.header.last_block_len = 0; 473 child_data_.header.last_block_len = 0;
472 child_data_.header.last_block = -1; 474 child_data_.header.last_block = -1;
473 } 475 }
474 476
475 return true; 477 return true;
476 } 478 }
477 479
478 void SparseControl::CloseChild() { 480 void SparseControl::CloseChild() {
479 scoped_refptr<net::WrappedIOBuffer> buf( 481 scoped_refptr<net::WrappedIOBuffer> buf(
480 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_))); 482 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_)));
481 483
482 // Save the allocation bitmap before closing the child entry. 484 // Save the allocation bitmap before closing the child entry.
483 int rv = child_->WriteData( 485 int rv = child_->WriteData(kSparseIndex, 0, buf, sizeof(child_data_),
484 kSparseIndex, 0, buf, sizeof(child_data_), net::CompletionCallback(), 486 CompletionCallback(),
485 false); 487 false);
486 if (rv != sizeof(child_data_)) 488 if (rv != sizeof(child_data_))
487 DLOG(ERROR) << "Failed to save child data"; 489 DLOG(ERROR) << "Failed to save child data";
488 child_->Release(); 490 child_->Release();
489 child_ = NULL; 491 child_ = NULL;
490 } 492 }
491 493
492 std::string SparseControl::GenerateChildKey() { 494 std::string SparseControl::GenerateChildKey() {
493 return GenerateChildName(entry_->GetKey(), sparse_header_.signature, 495 return GenerateChildName(entry_->GetKey(), sparse_header_.signature,
494 offset_ >> 20); 496 offset_ >> 20);
(...skipping 12 matching lines...) Expand all
507 return ContinueWithoutChild(key); 509 return ContinueWithoutChild(key);
508 } 510 }
509 511
510 // We were not able to open this child; see what we can do. 512 // We were not able to open this child; see what we can do.
511 bool SparseControl::ContinueWithoutChild(const std::string& key) { 513 bool SparseControl::ContinueWithoutChild(const std::string& key) {
512 if (kReadOperation == operation_) 514 if (kReadOperation == operation_)
513 return false; 515 return false;
514 if (kGetRangeOperation == operation_) 516 if (kGetRangeOperation == operation_)
515 return true; 517 return true;
516 518
519 if (!entry_->backend_)
520 return false;
521
517 child_ = entry_->backend_->CreateEntryImpl(key); 522 child_ = entry_->backend_->CreateEntryImpl(key);
518 if (!child_) { 523 if (!child_) {
519 child_ = NULL; 524 child_ = NULL;
520 result_ = net::ERR_CACHE_READ_FAILURE; 525 result_ = net::ERR_CACHE_READ_FAILURE;
521 return false; 526 return false;
522 } 527 }
523 // Write signature. 528 // Write signature.
524 InitChildData(); 529 InitChildData();
525 return true; 530 return true;
526 } 531 }
(...skipping 14 matching lines...) Expand all
541 children_map_.Resize(Bitmap::RequiredArraySize(child_bit + 1) * 32, true); 546 children_map_.Resize(Bitmap::RequiredArraySize(child_bit + 1) * 32, true);
542 547
543 children_map_.Set(child_bit, value); 548 children_map_.Set(child_bit, value);
544 } 549 }
545 550
546 void SparseControl::WriteSparseData() { 551 void SparseControl::WriteSparseData() {
547 scoped_refptr<net::IOBuffer> buf(new net::WrappedIOBuffer( 552 scoped_refptr<net::IOBuffer> buf(new net::WrappedIOBuffer(
548 reinterpret_cast<const char*>(children_map_.GetMap()))); 553 reinterpret_cast<const char*>(children_map_.GetMap())));
549 554
550 int len = children_map_.ArraySize() * 4; 555 int len = children_map_.ArraySize() * 4;
551 int rv = entry_->WriteData( 556 int rv = entry_->WriteData(kSparseIndex, sizeof(sparse_header_), buf, len,
552 kSparseIndex, sizeof(sparse_header_), buf, len, net::CompletionCallback(), 557 CompletionCallback(), false);
553 false);
554 if (rv != len) { 558 if (rv != len) {
555 DLOG(ERROR) << "Unable to save sparse map"; 559 DLOG(ERROR) << "Unable to save sparse map";
556 } 560 }
557 } 561 }
558 562
559 bool SparseControl::VerifyRange() { 563 bool SparseControl::VerifyRange() {
560 DCHECK_GE(result_, 0); 564 DCHECK_GE(result_, 0);
561 565
562 child_offset_ = static_cast<int>(offset_) & (kMaxEntrySize - 1); 566 child_offset_ = static_cast<int>(offset_) & (kMaxEntrySize - 1);
563 child_len_ = std::min(buf_len_, kMaxEntrySize - child_offset_); 567 child_len_ = std::min(buf_len_, kMaxEntrySize - child_offset_);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 // We know the real type of child_. 650 // We know the real type of child_.
647 EntryImpl* child = static_cast<EntryImpl*>(child_); 651 EntryImpl* child = static_cast<EntryImpl*>(child_);
648 child->SetEntryFlags(CHILD_ENTRY); 652 child->SetEntryFlags(CHILD_ENTRY);
649 653
650 memset(&child_data_, 0, sizeof(child_data_)); 654 memset(&child_data_, 0, sizeof(child_data_));
651 child_data_.header = sparse_header_; 655 child_data_.header = sparse_header_;
652 656
653 scoped_refptr<net::WrappedIOBuffer> buf( 657 scoped_refptr<net::WrappedIOBuffer> buf(
654 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_))); 658 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_)));
655 659
656 int rv = child_->WriteData( 660 int rv = child_->WriteData(kSparseIndex, 0, buf, sizeof(child_data_),
657 kSparseIndex, 0, buf, sizeof(child_data_), net::CompletionCallback(), 661 CompletionCallback(), false);
658 false);
659 if (rv != sizeof(child_data_)) 662 if (rv != sizeof(child_data_))
660 DLOG(ERROR) << "Failed to save child data"; 663 DLOG(ERROR) << "Failed to save child data";
661 SetChildBit(true); 664 SetChildBit(true);
662 } 665 }
663 666
664 void SparseControl::DoChildrenIO() { 667 void SparseControl::DoChildrenIO() {
665 while (DoChildIO()) continue; 668 while (DoChildIO()) continue;
666 669
667 // Range operations are finished synchronously, often without setting 670 // Range operations are finished synchronously, often without setting
668 // |finished_| to true. 671 // |finished_| to true.
(...skipping 20 matching lines...) Expand all
689 return false; 692 return false;
690 693
691 if (!OpenChild()) 694 if (!OpenChild())
692 return false; 695 return false;
693 696
694 if (!VerifyRange()) 697 if (!VerifyRange())
695 return false; 698 return false;
696 699
697 // We have more work to do. Let's not trigger a callback to the caller. 700 // We have more work to do. Let's not trigger a callback to the caller.
698 finished_ = false; 701 finished_ = false;
699 net::CompletionCallback callback; 702 CompletionCallback callback;
700 if (!user_callback_.is_null()) { 703 if (!user_callback_.is_null()) {
701 callback = 704 callback =
702 base::Bind(&SparseControl::OnChildIOCompleted, base::Unretained(this)); 705 base::Bind(&SparseControl::OnChildIOCompleted, base::Unretained(this));
703 } 706 }
704 707
705 int rv = 0; 708 int rv = 0;
706 switch (operation_) { 709 switch (operation_) {
707 case kReadOperation: 710 case kReadOperation:
708 if (entry_->net_log().IsLoggingAllEvents()) { 711 if (entry_->net_log().IsLoggingAllEvents()) {
709 entry_->net_log().BeginEvent( 712 entry_->net_log().BeginEvent(
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 return; 842 return;
840 } 843 }
841 844
842 // We are running a callback from the message loop. It's time to restart what 845 // We are running a callback from the message loop. It's time to restart what
843 // we were doing before. 846 // we were doing before.
844 DoChildrenIO(); 847 DoChildrenIO();
845 } 848 }
846 849
847 void SparseControl::DoUserCallback() { 850 void SparseControl::DoUserCallback() {
848 DCHECK(!user_callback_.is_null()); 851 DCHECK(!user_callback_.is_null());
849 net::CompletionCallback cb = user_callback_; 852 CompletionCallback cb = user_callback_;
850 user_callback_.Reset(); 853 user_callback_.Reset();
851 user_buf_ = NULL; 854 user_buf_ = NULL;
852 pending_ = false; 855 pending_ = false;
853 operation_ = kNoOperation; 856 operation_ = kNoOperation;
854 int rv = result_; 857 int rv = result_;
855 entry_->Release(); // Don't touch object after this line. 858 entry_->Release(); // Don't touch object after this line.
856 cb.Run(rv); 859 cb.Run(rv);
857 } 860 }
858 861
859 void SparseControl::DoAbortCallbacks() { 862 void SparseControl::DoAbortCallbacks() {
860 for (size_t i = 0; i < abort_callbacks_.size(); i++) { 863 for (size_t i = 0; i < abort_callbacks_.size(); i++) {
861 // Releasing all references to entry_ may result in the destruction of this 864 // Releasing all references to entry_ may result in the destruction of this
862 // object so we should not be touching it after the last Release(). 865 // object so we should not be touching it after the last Release().
863 net::CompletionCallback cb = abort_callbacks_[i]; 866 CompletionCallback cb = abort_callbacks_[i];
864 if (i == abort_callbacks_.size() - 1) 867 if (i == abort_callbacks_.size() - 1)
865 abort_callbacks_.clear(); 868 abort_callbacks_.clear();
866 869
867 entry_->Release(); // Don't touch object after this line. 870 entry_->Release(); // Don't touch object after this line.
868 cb.Run(net::OK); 871 cb.Run(net::OK);
869 } 872 }
870 } 873 }
871 874
872 } // namespace disk_cache 875 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698