OLD | NEW |
---|---|
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.h" | 5 #include "net/http/http_cache.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 | 10 |
(...skipping 12 matching lines...) Expand all Loading... | |
23 #include "base/pickle.h" | 23 #include "base/pickle.h" |
24 #include "base/stl_util.h" | 24 #include "base/stl_util.h" |
25 #include "base/string_number_conversions.h" | 25 #include "base/string_number_conversions.h" |
26 #include "base/string_util.h" | 26 #include "base/string_util.h" |
27 #include "base/stringprintf.h" | 27 #include "base/stringprintf.h" |
28 #include "net/base/io_buffer.h" | 28 #include "net/base/io_buffer.h" |
29 #include "net/base/load_flags.h" | 29 #include "net/base/load_flags.h" |
30 #include "net/base/net_errors.h" | 30 #include "net/base/net_errors.h" |
31 #include "net/base/upload_data_stream.h" | 31 #include "net/base/upload_data_stream.h" |
32 #include "net/disk_cache/disk_cache.h" | 32 #include "net/disk_cache/disk_cache.h" |
33 #include "net/disk_cache/pending_create_entry.h" | |
33 #include "net/http/http_cache_transaction.h" | 34 #include "net/http/http_cache_transaction.h" |
34 #include "net/http/http_network_layer.h" | 35 #include "net/http/http_network_layer.h" |
35 #include "net/http/http_network_session.h" | 36 #include "net/http/http_network_session.h" |
36 #include "net/http/http_request_info.h" | 37 #include "net/http/http_request_info.h" |
37 #include "net/http/http_response_headers.h" | 38 #include "net/http/http_response_headers.h" |
38 #include "net/http/http_response_info.h" | 39 #include "net/http/http_response_info.h" |
39 #include "net/http/http_util.h" | 40 #include "net/http/http_util.h" |
40 | 41 |
41 namespace net { | 42 namespace net { |
42 | 43 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 CompletionCallback callback; // BackendCallback. | 96 CompletionCallback callback; // BackendCallback. |
96 WorkItemList pending_queue; | 97 WorkItemList pending_queue; |
97 }; | 98 }; |
98 | 99 |
99 //----------------------------------------------------------------------------- | 100 //----------------------------------------------------------------------------- |
100 | 101 |
101 // The type of operation represented by a work item. | 102 // The type of operation represented by a work item. |
102 enum WorkItemOperation { | 103 enum WorkItemOperation { |
103 WI_CREATE_BACKEND, | 104 WI_CREATE_BACKEND, |
104 WI_OPEN_ENTRY, | 105 WI_OPEN_ENTRY, |
105 WI_CREATE_ENTRY, | |
106 WI_DOOM_ENTRY | 106 WI_DOOM_ENTRY |
107 }; | 107 }; |
108 | 108 |
109 // A work item encapsulates a single request to the backend with all the | 109 // A work item encapsulates a single request to the backend with all the |
110 // information needed to complete that request. | 110 // information needed to complete that request. |
111 class HttpCache::WorkItem { | 111 class HttpCache::WorkItem { |
112 public: | 112 public: |
113 WorkItem(WorkItemOperation operation, Transaction* trans, ActiveEntry** entry) | 113 WorkItem(WorkItemOperation operation, Transaction* trans, ActiveEntry** entry) |
114 : operation_(operation), | 114 : operation_(operation), |
115 trans_(trans), | 115 trans_(trans), |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
705 item->ClearTransaction(); | 705 item->ClearTransaction(); |
706 pending_op->callback.Run(rv); | 706 pending_op->callback.Run(rv); |
707 } | 707 } |
708 | 708 |
709 return rv; | 709 return rv; |
710 } | 710 } |
711 | 711 |
712 int HttpCache::CreateEntry(const std::string& key, ActiveEntry** entry, | 712 int HttpCache::CreateEntry(const std::string& key, ActiveEntry** entry, |
713 Transaction* trans) { | 713 Transaction* trans) { |
714 DCHECK(!FindActiveEntry(key)); | 714 DCHECK(!FindActiveEntry(key)); |
715 | 715 disk_cache::Entry* new_entry; |
716 WorkItem* item = new WorkItem(WI_CREATE_ENTRY, trans, entry); | 716 int rv = disk_cache::PendingCreateEntry(disk_cache_.get(), key, &new_entry); |
rvargas (doing something else)
2013/01/23 22:04:09
why is this not calling CreateEntry?. I mean, if y
gavinp
2013/01/24 07:38:10
Good point. And if we want to do A/B tests (and we
| |
717 PendingOp* pending_op = GetPendingOp(key); | 717 if (rv == net::OK) |
718 if (pending_op->writer) { | 718 *entry = ActivateEntry(new_entry); |
719 pending_op->pending_queue.push_back(item); | |
720 return ERR_IO_PENDING; | |
721 } | |
722 | |
723 DCHECK(pending_op->pending_queue.empty()); | |
724 | |
725 pending_op->writer = item; | |
726 pending_op->callback = base::Bind(&HttpCache::OnPendingOpComplete, | |
727 AsWeakPtr(), pending_op); | |
728 | |
729 int rv = disk_cache_->CreateEntry(key, &(pending_op->disk_entry), | |
730 pending_op->callback); | |
731 if (rv != ERR_IO_PENDING) { | |
732 item->ClearTransaction(); | |
733 pending_op->callback.Run(rv); | |
734 } | |
735 | |
736 return rv; | 719 return rv; |
737 } | 720 } |
738 | 721 |
739 void HttpCache::DestroyEntry(ActiveEntry* entry) { | 722 void HttpCache::DestroyEntry(ActiveEntry* entry) { |
740 if (entry->doomed) { | 723 if (entry->doomed) { |
741 FinalizeDoomedEntry(entry); | 724 FinalizeDoomedEntry(entry); |
742 } else { | 725 } else { |
743 DeactivateEntry(entry); | 726 DeactivateEntry(entry); |
744 } | 727 } |
745 } | 728 } |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
993 std::string key; | 976 std::string key; |
994 if (result == OK) { | 977 if (result == OK) { |
995 if (op == WI_DOOM_ENTRY) { | 978 if (op == WI_DOOM_ENTRY) { |
996 // Anything after a Doom has to be restarted. | 979 // Anything after a Doom has to be restarted. |
997 fail_requests = true; | 980 fail_requests = true; |
998 } else if (item->IsValid()) { | 981 } else if (item->IsValid()) { |
999 key = pending_op->disk_entry->GetKey(); | 982 key = pending_op->disk_entry->GetKey(); |
1000 entry = ActivateEntry(pending_op->disk_entry); | 983 entry = ActivateEntry(pending_op->disk_entry); |
1001 } else { | 984 } else { |
1002 // The writer transaction is gone. | 985 // The writer transaction is gone. |
1003 if (op == WI_CREATE_ENTRY) | |
1004 pending_op->disk_entry->Doom(); | |
1005 pending_op->disk_entry->Close(); | 986 pending_op->disk_entry->Close(); |
1006 pending_op->disk_entry = NULL; | 987 pending_op->disk_entry = NULL; |
1007 fail_requests = true; | 988 fail_requests = true; |
1008 } | 989 } |
1009 } | 990 } |
1010 | 991 |
1011 // We are about to notify a bunch of transactions, and they may decide to | 992 // We are about to notify a bunch of transactions, and they may decide to |
1012 // re-issue a request (or send a different one). If we don't delete | 993 // re-issue a request (or send a different one). If we don't delete |
1013 // pending_op, the new request will be appended to the end of the list, and | 994 // pending_op, the new request will be appended to the end of the list, and |
1014 // we'll see it again from this point before it has a chance to complete (and | 995 // we'll see it again from this point before it has a chance to complete (and |
(...skipping 21 matching lines...) Expand all Loading... | |
1036 entry = FindActiveEntry(key); | 1017 entry = FindActiveEntry(key); |
1037 if (!entry) | 1018 if (!entry) |
1038 fail_requests = true; | 1019 fail_requests = true; |
1039 } | 1020 } |
1040 | 1021 |
1041 if (fail_requests) { | 1022 if (fail_requests) { |
1042 item->NotifyTransaction(ERR_CACHE_RACE, NULL); | 1023 item->NotifyTransaction(ERR_CACHE_RACE, NULL); |
1043 continue; | 1024 continue; |
1044 } | 1025 } |
1045 | 1026 |
1046 if (item->operation() == WI_CREATE_ENTRY) { | 1027 item->NotifyTransaction(result, entry); |
1047 if (result == OK) { | |
1048 // A second Create request, but the first request succeeded. | |
1049 item->NotifyTransaction(ERR_CACHE_CREATE_FAILURE, NULL); | |
1050 } else { | |
1051 if (op != WI_CREATE_ENTRY) { | |
1052 // Failed Open followed by a Create. | |
1053 item->NotifyTransaction(ERR_CACHE_RACE, NULL); | |
1054 fail_requests = true; | |
1055 } else { | |
1056 item->NotifyTransaction(result, entry); | |
1057 } | |
1058 } | |
1059 } else { | |
1060 if (op == WI_CREATE_ENTRY && result != OK) { | |
1061 // Failed Create followed by an Open. | |
1062 item->NotifyTransaction(ERR_CACHE_RACE, NULL); | |
1063 fail_requests = true; | |
1064 } else { | |
1065 item->NotifyTransaction(result, entry); | |
1066 } | |
1067 } | |
1068 } | 1028 } |
1069 } | 1029 } |
1070 | 1030 |
1071 // static | 1031 // static |
1072 void HttpCache::OnPendingOpComplete(const base::WeakPtr<HttpCache>& cache, | 1032 void HttpCache::OnPendingOpComplete(const base::WeakPtr<HttpCache>& cache, |
1073 PendingOp* pending_op, | 1033 PendingOp* pending_op, |
1074 int rv) { | 1034 int rv) { |
1075 if (cache.get()) { | 1035 if (cache.get()) { |
1076 cache->OnIOComplete(rv, pending_op); | 1036 cache->OnIOComplete(rv, pending_op); |
1077 } else { | 1037 } else { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1116 building_backend_ = false; | 1076 building_backend_ = false; |
1117 DeletePendingOp(pending_op); | 1077 DeletePendingOp(pending_op); |
1118 } | 1078 } |
1119 | 1079 |
1120 // The cache may be gone when we return from the callback. | 1080 // The cache may be gone when we return from the callback. |
1121 if (!item->DoCallback(result, backend)) | 1081 if (!item->DoCallback(result, backend)) |
1122 item->NotifyTransaction(result, NULL); | 1082 item->NotifyTransaction(result, NULL); |
1123 } | 1083 } |
1124 | 1084 |
1125 } // namespace net | 1085 } // namespace net |
OLD | NEW |