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

Side by Side Diff: net/http/http_cache_transaction.cc

Issue 2721933002: HttpCache::Transaction layer allowing parallel validation (Closed)
Patch Set: Feedback addressed, more tests and refactoring Created 3 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
OLDNEW
1 // Copyright (c) 2012 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/http/http_cache_transaction.h" 5 #include "net/http/http_cache_transaction.h"
6 6
7 #include "build/build_config.h" // For OS_POSIX 7 #include "build/build_config.h" // For OS_POSIX
8 8
9 #if defined(OS_POSIX) 9 #if defined(OS_POSIX)
10 #include <unistd.h> 10 #include <unistd.h>
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> 593 // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* ->
594 // PartialHeadersReceived 594 // PartialHeadersReceived
595 // 595 //
596 // Read(): 596 // Read():
597 // NetworkRead* -> CacheWriteData* 597 // NetworkRead* -> CacheWriteData*
598 // 598 //
599 // 2. Cached entry, no validation: 599 // 2. Cached entry, no validation:
600 // Start(): 600 // Start():
601 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 601 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
602 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 602 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
603 // BeginCacheValidation() -> SetupEntryForRead() 603 // BeginCacheValidation() -> SetupEntryForRead() -> WaitBeforeRead*
604 // 604 //
605 // Read(): 605 // Read():
606 // CacheReadData* 606 // CacheReadData*
607 // 607 //
608 // 3. Cached entry, validation (304): 608 // 3. Cached entry, validation (304):
609 // Start(): 609 // Start():
610 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 610 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
611 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 611 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
612 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> 612 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest ->
613 // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> 613 // UpdateCachedResponse -> CacheWriteUpdatedResponse* ->
614 // UpdateCachedResponseComplete -> OverwriteCachedResponse -> 614 // UpdateCachedResponseComplete -> OverwriteCachedResponse ->
615 // PartialHeadersReceived 615 // PartialHeadersReceived -> WaitBeforeRead*
616 // 616 //
617 // Read(): 617 // Read():
618 // CacheReadData* 618 // CacheReadData*
619 // 619 //
620 // 4. Cached entry, validation and replace (200): 620 // 4. Cached entry, validation and replace (200):
621 // Start(): 621 // Start():
622 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* 622 // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
623 // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> 623 // -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
624 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> 624 // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest ->
625 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> 625 // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* ->
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 // BeginPartialCacheValidation() -> BeginCacheValidation() -> 705 // BeginPartialCacheValidation() -> BeginCacheValidation() ->
706 // SetupEntryForRead() 706 // SetupEntryForRead()
707 // 707 //
708 // Read(): 708 // Read():
709 // CacheReadData* 709 // CacheReadData*
710 // 710 //
711 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true: 711 // 14. Cached entry more than 5 minutes old, unused_since_prefetch is true:
712 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between 712 // Like examples 2-4, only CacheToggleUnusedSincePrefetch* is inserted between
713 // CacheReadResponse* and CacheDispatchValidation. 713 // CacheReadResponse* and CacheDispatchValidation.
714 int HttpCache::Transaction::DoLoop(int result) { 714 int HttpCache::Transaction::DoLoop(int result) {
715 int rv = DoLoopImpl(result);
716
717 // If its the end of the Start() state machine, the transaction might have to
718 // wait before it can read from the cache if there is another transaction
719 // writing to the cache currently. This is being done to enable parallelizing
720 // the validation phase of a transaction while another transaction is still
721 // writing the response to the cache.
722 // Checking reading_ will make sure that the control is still in the start
723 // state machine and also that we do not enter the wait state for
724 // partial requests that have already started reading and re-entered the
725 // start() state machine.
726 if (!reading_ && rv == OK) {
727 next_state_ = STATE_WAIT_BEFORE_READ;
728 rv = DoLoopImpl(rv);
729 }
730
731 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
732 read_buf_ = nullptr; // Release the buffer before invoking the callback.
733 base::ResetAndReturn(&callback_).Run(rv);
734 }
735
736 return rv;
737 }
738
739 int HttpCache::Transaction::DoLoopImpl(int result) {
715 DCHECK(next_state_ != STATE_NONE); 740 DCHECK(next_state_ != STATE_NONE);
716 741
717 int rv = result; 742 int rv = result;
718 do { 743 do {
719 State state = next_state_; 744 State state = next_state_;
720 next_state_ = STATE_NONE; 745 next_state_ = STATE_NONE;
721 switch (state) { 746 switch (state) {
722 case STATE_GET_BACKEND: 747 case STATE_GET_BACKEND:
723 DCHECK_EQ(OK, rv); 748 DCHECK_EQ(OK, rv);
724 rv = DoGetBackend(); 749 rv = DoGetBackend();
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 DCHECK_EQ(OK, rv); 869 DCHECK_EQ(OK, rv);
845 rv = DoPartialHeadersReceived(); 870 rv = DoPartialHeadersReceived();
846 break; 871 break;
847 case STATE_CACHE_READ_METADATA: 872 case STATE_CACHE_READ_METADATA:
848 DCHECK_EQ(OK, rv); 873 DCHECK_EQ(OK, rv);
849 rv = DoCacheReadMetadata(); 874 rv = DoCacheReadMetadata();
850 break; 875 break;
851 case STATE_CACHE_READ_METADATA_COMPLETE: 876 case STATE_CACHE_READ_METADATA_COMPLETE:
852 rv = DoCacheReadMetadataComplete(rv); 877 rv = DoCacheReadMetadataComplete(rv);
853 break; 878 break;
879 case STATE_WAIT_BEFORE_READ:
880 DCHECK_EQ(OK, rv);
881 rv = DoWaitBeforeRead();
882 break;
883 case STATE_WAIT_BEFORE_READ_COMPLETE:
884 rv = DoWaitBeforeReadComplete(rv);
885 break;
854 case STATE_NETWORK_READ: 886 case STATE_NETWORK_READ:
855 DCHECK_EQ(OK, rv); 887 DCHECK_EQ(OK, rv);
856 rv = DoNetworkRead(); 888 rv = DoNetworkRead();
857 break; 889 break;
858 case STATE_NETWORK_READ_COMPLETE: 890 case STATE_NETWORK_READ_COMPLETE:
859 rv = DoNetworkReadComplete(rv); 891 rv = DoNetworkReadComplete(rv);
860 break; 892 break;
861 case STATE_CACHE_READ_DATA: 893 case STATE_CACHE_READ_DATA:
862 DCHECK_EQ(OK, rv); 894 DCHECK_EQ(OK, rv);
863 rv = DoCacheReadData(); 895 rv = DoCacheReadData();
(...skipping 14 matching lines...) Expand all
878 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE: 910 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE:
879 rv = DoCacheWriteTruncatedResponseComplete(rv); 911 rv = DoCacheWriteTruncatedResponseComplete(rv);
880 break; 912 break;
881 default: 913 default:
882 NOTREACHED() << "bad state"; 914 NOTREACHED() << "bad state";
883 rv = ERR_FAILED; 915 rv = ERR_FAILED;
884 break; 916 break;
885 } 917 }
886 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 918 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
887 919
888 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
889 read_buf_ = NULL; // Release the buffer before invoking the callback.
890 base::ResetAndReturn(&callback_).Run(rv);
891 }
892
893 return rv; 920 return rv;
894 } 921 }
895 922
896 int HttpCache::Transaction::DoGetBackend() { 923 int HttpCache::Transaction::DoGetBackend() {
897 cache_pending_ = true; 924 cache_pending_ = true;
898 next_state_ = STATE_GET_BACKEND_COMPLETE; 925 next_state_ = STATE_GET_BACKEND_COMPLETE;
899 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_GET_BACKEND); 926 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_GET_BACKEND);
900 return cache_->GetBackendForTransaction(this); 927 return cache_->GetBackendForTransaction(this);
901 } 928 }
902 929
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1490 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_NOT_IN_CACHE); 1517 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_NOT_IN_CACHE);
1491 } 1518 }
1492 1519
1493 // Invalidate any cached GET with a successful PUT or DELETE. 1520 // Invalidate any cached GET with a successful PUT or DELETE.
1494 if (mode_ == WRITE && 1521 if (mode_ == WRITE &&
1495 (request_->method == "PUT" || request_->method == "DELETE")) { 1522 (request_->method == "PUT" || request_->method == "DELETE")) {
1496 if (NonErrorResponse(new_response->headers->response_code())) { 1523 if (NonErrorResponse(new_response->headers->response_code())) {
1497 int ret = cache_->DoomEntry(cache_key_, NULL); 1524 int ret = cache_->DoomEntry(cache_key_, NULL);
1498 DCHECK_EQ(OK, ret); 1525 DCHECK_EQ(OK, ret);
1499 } 1526 }
1500 cache_->DoneWritingToEntry(entry_, true); 1527 cache_->DoneWritingToEntry(entry_, true, this);
1501 entry_ = NULL; 1528 entry_ = NULL;
1502 mode_ = NONE; 1529 mode_ = NONE;
1503 } 1530 }
1504 1531
1505 // Invalidate any cached GET with a successful POST. 1532 // Invalidate any cached GET with a successful POST.
1506 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) && 1533 if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) &&
1507 request_->method == "POST" && 1534 request_->method == "POST" &&
1508 NonErrorResponse(new_response->headers->response_code())) { 1535 NonErrorResponse(new_response->headers->response_code())) {
1509 cache_->DoomMainEntryForUrl(request_->url); 1536 cache_->DoomMainEntryForUrl(request_->url);
1510 } 1537 }
(...skipping 12 matching lines...) Expand all
1523 if (new_response->headers->response_code() == 304 || handling_206_) { 1550 if (new_response->headers->response_code() == 304 || handling_206_) {
1524 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED); 1551 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_VALIDATED);
1525 next_state_ = STATE_UPDATE_CACHED_RESPONSE; 1552 next_state_ = STATE_UPDATE_CACHED_RESPONSE;
1526 return OK; 1553 return OK;
1527 } 1554 }
1528 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED); 1555 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_UPDATED);
1529 mode_ = WRITE; 1556 mode_ = WRITE;
1530 } 1557 }
1531 1558
1532 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE; 1559 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE;
1560
1561 if (!entry_)
1562 return OK;
1563
1564 // If this is the writer, give chance to another transaction to start
1565 // validation.
1566 if (entry_->writer == this && request_->method != "HEAD") {
1567 cache_->DoneValidationWriteEntry(entry_, this);
1568 return OK;
1569 }
1570
1571 // Invalidate any current entry with a successful response.
1572 if (new_response->headers->response_code() != 304) {
1573 DCHECK_EQ(entry_->validating_transaction, this);
1574 cache_->DoneValidationWithEntry(entry_, this, false);
1575 entry_ = nullptr;
1576 mode_ = NONE;
1577 return OK;
1578 }
1579
1533 return OK; 1580 return OK;
1534 } 1581 }
1535 1582
1536 // We received 304 or 206 and we want to update the cached response headers. 1583 // We received 304 or 206 and we want to update the cached response headers.
1537 int HttpCache::Transaction::DoUpdateCachedResponse() { 1584 int HttpCache::Transaction::DoUpdateCachedResponse() {
1538 TRACE_EVENT0("io", "HttpCacheTransaction::DoUpdateCachedResponse"); 1585 TRACE_EVENT0("io", "HttpCacheTransaction::DoUpdateCachedResponse");
1539 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE; 1586 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE;
1540 int rv = OK; 1587 int rv = OK;
1541 // Update the cached response based on the headers and properties of 1588 // Update the cached response based on the headers and properties of
1542 // new_response_. 1589 // new_response_.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 DCHECK(!handling_206_); 1639 DCHECK(!handling_206_);
1593 // We got a "not modified" response and already updated the corresponding 1640 // We got a "not modified" response and already updated the corresponding
1594 // cache entry above. 1641 // cache entry above.
1595 // 1642 //
1596 // By closing the cached entry now, we make sure that the 304 rather than 1643 // By closing the cached entry now, we make sure that the 304 rather than
1597 // the cached 200 response, is what will be returned to the user. 1644 // the cached 200 response, is what will be returned to the user.
1598 DoneWritingToEntry(true); 1645 DoneWritingToEntry(true);
1599 } else if (entry_ && !handling_206_) { 1646 } else if (entry_ && !handling_206_) {
1600 DCHECK_EQ(READ_WRITE, mode_); 1647 DCHECK_EQ(READ_WRITE, mode_);
1601 if (!partial_ || partial_->IsLastRange()) { 1648 if (!partial_ || partial_->IsLastRange()) {
1602 cache_->ConvertWriterToReader(entry_); 1649 if (cache_->ConvertWriterToReader(entry_, this))
1603 mode_ = READ; 1650 mode_ = READ;
1604 } 1651 }
1605 // We no longer need the network transaction, so destroy it. 1652 // We no longer need the network transaction, so destroy it.
1606 ResetNetworkTransaction(); 1653 ResetNetworkTransaction();
1607 } else if (entry_ && handling_206_ && truncated_ && 1654 } else if (entry_ && handling_206_ && truncated_ &&
1608 partial_->initial_validation()) { 1655 partial_->initial_validation()) {
1609 // We just finished the validation of a truncated entry, and the server 1656 // We just finished the validation of a truncated entry, and the server
1610 // is willing to resume the operation. Now we go back and start serving 1657 // is willing to resume the operation. Now we go back and start serving
1611 // the first part to the user. 1658 // the first part to the user.
1612 ResetNetworkTransaction(); 1659 ResetNetworkTransaction();
1613 new_response_ = NULL; 1660 new_response_ = NULL;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 next_state_ = STATE_CACHE_READ_DATA; 1776 next_state_ = STATE_CACHE_READ_DATA;
1730 } 1777 }
1731 } else if (mode_ != NONE) { 1778 } else if (mode_ != NONE) {
1732 // We are about to return the headers for a byte-range request to the user, 1779 // We are about to return the headers for a byte-range request to the user,
1733 // so let's fix them. 1780 // so let's fix them.
1734 partial_->FixResponseHeaders(response_.headers.get(), true); 1781 partial_->FixResponseHeaders(response_.headers.get(), true);
1735 } 1782 }
1736 return OK; 1783 return OK;
1737 } 1784 }
1738 1785
1786 int HttpCache::Transaction::DoWaitBeforeRead() {
1787 if (!entry_)
1788 return OK;
1789
1790 next_state_ = STATE_WAIT_BEFORE_READ_COMPLETE;
1791
1792 // If this is the writer, it does not need to wait.
1793 if (entry_->writer == this)
1794 return OK;
1795
1796 // If the transaction was converted to a reader but not in readers yet, then
1797 // it must be added to the queue and another transaction can start the
1798 // validation phase. If the transaction was already successfully added as a
1799 // reader then do nothing since it does not need to wait and processing
1800 // another transaction would already have been taken care of by calling
1801 // ConvertWriterToReader.
1802 if (entry_->validating_transaction == this && !entry_->IsReader(this))
1803 return cache_->DoneValidationWithEntry(entry_, this, true);
1804
1805 return OK;
1806 }
1807
1808 int HttpCache::Transaction::DoWaitBeforeReadComplete(int rv) {
1809 if (rv == ERR_CACHE_RACE) {
1810 next_state_ = STATE_INIT_ENTRY;
1811 cache_entry_status_ = CacheEntryStatus::ENTRY_UNDEFINED;
1812 entry_ = nullptr;
1813 if (network_trans_)
1814 network_trans_.reset();
1815 return OK;
1816 }
1817
1818 if (rv != OK)
1819 return rv;
1820
1821 // If successful then this must be either be the writer or a reader as the
1822 // response must have completely been written to the cache.
1823 if (entry_->writer == this)
1824 return OK;
1825
1826 mode_ = READ;
1827 if (network_trans_)
1828 ResetNetworkTransaction();
1829 return OK;
1830 }
1831
1739 int HttpCache::Transaction::DoCacheReadMetadata() { 1832 int HttpCache::Transaction::DoCacheReadMetadata() {
1740 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadata"); 1833 TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadata");
1741 DCHECK(entry_); 1834 DCHECK(entry_);
1742 DCHECK(!response_.metadata.get()); 1835 DCHECK(!response_.metadata.get());
1743 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE; 1836 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE;
1744 1837
1745 response_.metadata = 1838 response_.metadata =
1746 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); 1839 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex));
1747 1840
1748 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO); 1841 net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO);
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 if (partial_) { 2651 if (partial_) {
2559 if (truncated_ || is_sparse_ || !invalid_range_) { 2652 if (truncated_ || is_sparse_ || !invalid_range_) {
2560 // We are going to return the saved response headers to the caller, so 2653 // We are going to return the saved response headers to the caller, so
2561 // we may need to adjust them first. 2654 // we may need to adjust them first.
2562 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED; 2655 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED;
2563 return OK; 2656 return OK;
2564 } else { 2657 } else {
2565 partial_.reset(); 2658 partial_.reset();
2566 } 2659 }
2567 } 2660 }
2568 cache_->ConvertWriterToReader(entry_); 2661
2569 mode_ = READ; 2662 // This might or might not be able to add it as an active reader based on
2663 // whether this is the active writer or not. If not, it will be added to a
2664 // wait queue in DoWaitBeforeRead.
2665 if (cache_->ConvertWriterToReader(entry_, this))
2666 mode_ = READ;
2570 2667
2571 if (request_->method == "HEAD") 2668 if (request_->method == "HEAD")
2572 FixHeadersForHead(); 2669 FixHeadersForHead();
2573 2670
2574 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) 2671 if (entry_->disk_entry->GetDataSize(kMetadataIndex))
2575 next_state_ = STATE_CACHE_READ_METADATA; 2672 next_state_ = STATE_CACHE_READ_METADATA;
2576 return OK; 2673 return OK;
2577 } 2674 }
2578 2675
2579 int HttpCache::Transaction::WriteToEntry(int index, int offset, 2676 int HttpCache::Transaction::WriteToEntry(int index, int offset,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 } 2741 }
2645 return OK; 2742 return OK;
2646 } 2743 }
2647 2744
2648 void HttpCache::Transaction::DoneWritingToEntry(bool success) { 2745 void HttpCache::Transaction::DoneWritingToEntry(bool success) {
2649 if (!entry_) 2746 if (!entry_)
2650 return; 2747 return;
2651 2748
2652 RecordHistograms(); 2749 RecordHistograms();
2653 2750
2654 cache_->DoneWritingToEntry(entry_, success); 2751 cache_->DoneWritingToEntry(entry_, success, this);
2655 entry_ = NULL; 2752 entry_ = NULL;
2656 mode_ = NONE; // switch to 'pass through' mode 2753 mode_ = NONE; // switch to 'pass through' mode
2657 } 2754 }
2658 2755
2659 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) { 2756 int HttpCache::Transaction::OnCacheReadError(int result, bool restart) {
2660 DLOG(ERROR) << "ReadData failed: " << result; 2757 DLOG(ERROR) << "ReadData failed: " << result;
2661 const int result_for_histogram = std::max(0, -result); 2758 const int result_for_histogram = std::max(0, -result);
2662 if (restart) { 2759 if (restart) {
2663 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable", 2760 UMA_HISTOGRAM_SPARSE_SLOWLY("HttpCache.ReadErrorRestartable",
2664 result_for_histogram); 2761 result_for_histogram);
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
3000 default: 3097 default:
3001 NOTREACHED(); 3098 NOTREACHED();
3002 } 3099 }
3003 } 3100 }
3004 3101
3005 void HttpCache::Transaction::OnIOComplete(int result) { 3102 void HttpCache::Transaction::OnIOComplete(int result) {
3006 DoLoop(result); 3103 DoLoop(result);
3007 } 3104 }
3008 3105
3009 } // namespace net 3106 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698