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

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

Issue 111005: Bypass the cache for the second or later HttpCache::Transaction... Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 6 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
« no previous file with comments | « net/base/load_states.h ('k') | net/http/http_network_transaction.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 // This bit is set if the response info has vary header data. 60 // This bit is set if the response info has vary header data.
61 RESPONSE_INFO_HAS_VARY_DATA = 1 << 11, 61 RESPONSE_INFO_HAS_VARY_DATA = 1 << 11,
62 62
63 // TODO(darin): Add other bits to indicate alternate request methods and 63 // TODO(darin): Add other bits to indicate alternate request methods and
64 // whether or not we are storing a partial document. For now, we don't 64 // whether or not we are storing a partial document. For now, we don't
65 // support storing those. 65 // support storing those.
66 }; 66 };
67 67
68 //----------------------------------------------------------------------------- 68 //-----------------------------------------------------------------------------
69 69
70 static int kTransactionTimeoutInMillisecond = 5000;
71
70 struct HeaderNameAndValue { 72 struct HeaderNameAndValue {
71 const char* name; 73 const char* name;
72 const char* value; 74 const char* value;
73 }; 75 };
74 76
75 // If the request includes one of these request headers, then avoid caching 77 // If the request includes one of these request headers, then avoid caching
76 // to avoid getting confused. 78 // to avoid getting confused.
77 static const HeaderNameAndValue kPassThroughHeaders[] = { 79 static const HeaderNameAndValue kPassThroughHeaders[] = {
78 { "range", NULL }, // causes unexpected 206s 80 { "range", NULL }, // causes unexpected 206s
79 { "if-modified-since", NULL }, // causes unexpected 304s 81 { "if-modified-since", NULL }, // causes unexpected 304s
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 mode_(NONE), 149 mode_(NONE),
148 read_offset_(0), 150 read_offset_(0),
149 effective_load_flags_(0), 151 effective_load_flags_(0),
150 final_upload_progress_(0), 152 final_upload_progress_(0),
151 ALLOW_THIS_IN_INITIALIZER_LIST( 153 ALLOW_THIS_IN_INITIALIZER_LIST(
152 network_info_callback_(this, &Transaction::OnNetworkInfoAvailable)), 154 network_info_callback_(this, &Transaction::OnNetworkInfoAvailable)),
153 ALLOW_THIS_IN_INITIALIZER_LIST( 155 ALLOW_THIS_IN_INITIALIZER_LIST(
154 network_read_callback_(this, &Transaction::OnNetworkReadCompleted)), 156 network_read_callback_(this, &Transaction::OnNetworkReadCompleted)),
155 ALLOW_THIS_IN_INITIALIZER_LIST( 157 ALLOW_THIS_IN_INITIALIZER_LIST(
156 cache_read_callback_(new CancelableCompletionCallback<Transaction>( 158 cache_read_callback_(new CancelableCompletionCallback<Transaction>(
157 this, &Transaction::OnCacheReadCompleted))) { 159 this, &Transaction::OnCacheReadCompleted))),
160 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
161 is_waiting_for_entry_(false) {
158 } 162 }
159 163
160 // Clean up the transaction. 164 // Clean up the transaction.
161 virtual ~Transaction(); 165 virtual ~Transaction();
162 166
163 // HttpTransaction methods: 167 // HttpTransaction methods:
164 virtual int Start(const HttpRequestInfo*, CompletionCallback*); 168 virtual int Start(const HttpRequestInfo*, CompletionCallback*);
165 virtual int RestartIgnoringLastError(CompletionCallback*); 169 virtual int RestartIgnoringLastError(CompletionCallback*);
166 virtual int RestartWithAuth(const std::wstring& username, 170 virtual int RestartWithAuth(const std::wstring& username,
167 const std::wstring& password, 171 const std::wstring& password,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 203
200 const std::string& key() const { return cache_key_; } 204 const std::string& key() const { return cache_key_; }
201 205
202 // Associates this transaction with a cache entry. 206 // Associates this transaction with a cache entry.
203 int AddToEntry(); 207 int AddToEntry();
204 208
205 // Called by the HttpCache when the given disk cache entry becomes accessible 209 // Called by the HttpCache when the given disk cache entry becomes accessible
206 // to the transaction. Returns network error code. 210 // to the transaction. Returns network error code.
207 int EntryAvailable(ActiveEntry* entry); 211 int EntryAvailable(ActiveEntry* entry);
208 212
213 // Called by the HttpCache when the given disk cache entry is busy. Sets up
214 // a timeout alarm to MessageLoop.
215 void PendOnEntry(ActiveEntry* entry);
216
209 private: 217 private:
210 // This is a helper function used to trigger a completion callback. It may 218 // This is a helper function used to trigger a completion callback. It may
211 // only be called if callback_ is non-null. 219 // only be called if callback_ is non-null.
212 void DoCallback(int rv); 220 void DoCallback(int rv);
213 221
214 // This will trigger the completion callback if appropriate. 222 // This will trigger the completion callback if appropriate.
215 int HandleResult(int rv); 223 int HandleResult(int rv);
216 224
217 // Set request_ and fields derived from it. 225 // Set request_ and fields derived from it.
218 void SetRequest(const HttpRequestInfo* request); 226 void SetRequest(const HttpRequestInfo* request);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 279
272 // Called to signal completion of the network transaction's Start method: 280 // Called to signal completion of the network transaction's Start method:
273 void OnNetworkInfoAvailable(int result); 281 void OnNetworkInfoAvailable(int result);
274 282
275 // Called to signal completion of the network transaction's Read method: 283 // Called to signal completion of the network transaction's Read method:
276 void OnNetworkReadCompleted(int result); 284 void OnNetworkReadCompleted(int result);
277 285
278 // Called to signal completion of the cache's ReadData method: 286 // Called to signal completion of the cache's ReadData method:
279 void OnCacheReadCompleted(int result); 287 void OnCacheReadCompleted(int result);
280 288
289 // Called to bypass cache when it took too much time to get access to cache.
290 void OnAddToEntryTimeout(ActiveEntry* entry);
291
281 const HttpRequestInfo* request_; 292 const HttpRequestInfo* request_;
282 scoped_ptr<HttpRequestInfo> custom_request_; 293 scoped_ptr<HttpRequestInfo> custom_request_;
283 HttpCache* cache_; 294 HttpCache* cache_;
284 HttpCache::ActiveEntry* entry_; 295 HttpCache::ActiveEntry* entry_;
285 scoped_ptr<HttpTransaction> network_trans_; 296 scoped_ptr<HttpTransaction> network_trans_;
286 CompletionCallback* callback_; // consumer's callback 297 CompletionCallback* callback_; // consumer's callback
287 HttpResponseInfo response_; 298 HttpResponseInfo response_;
288 HttpResponseInfo auth_response_; 299 HttpResponseInfo auth_response_;
289 std::string cache_key_; 300 std::string cache_key_;
290 Mode mode_; 301 Mode mode_;
291 scoped_refptr<IOBuffer> read_buf_; 302 scoped_refptr<IOBuffer> read_buf_;
292 int read_offset_; 303 int read_offset_;
293 int effective_load_flags_; 304 int effective_load_flags_;
294 uint64 final_upload_progress_; 305 uint64 final_upload_progress_;
295 CompletionCallbackImpl<Transaction> network_info_callback_; 306 CompletionCallbackImpl<Transaction> network_info_callback_;
296 CompletionCallbackImpl<Transaction> network_read_callback_; 307 CompletionCallbackImpl<Transaction> network_read_callback_;
297 scoped_refptr<CancelableCompletionCallback<Transaction> > 308 scoped_refptr<CancelableCompletionCallback<Transaction> >
298 cache_read_callback_; 309 cache_read_callback_;
310
311 ScopedRunnableMethodFactory<Transaction> task_factory_;
312 bool is_waiting_for_entry_;
299 }; 313 };
300 314
301 HttpCache::Transaction::~Transaction() { 315 HttpCache::Transaction::~Transaction() {
302 if (!revoked()) { 316 if (!revoked()) {
303 if (entry_) { 317 if (entry_) {
304 cache_->DoneWithEntry(entry_, this); 318 cache_->DoneWithEntry(entry_, this);
305 } else { 319 } else {
306 cache_->RemovePendingTransaction(this); 320 cache_->RemovePendingTransaction(this);
307 } 321 }
308 } 322 }
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 // 545 //
532 // o if we are a reader for the transaction, then we can start reading the 546 // o if we are a reader for the transaction, then we can start reading the
533 // cache entry. 547 // cache entry.
534 // 548 //
535 // o if we can read or write, then we should check if the cache entry needs 549 // o if we can read or write, then we should check if the cache entry needs
536 // to be validated and then issue a network request if needed or just read 550 // to be validated and then issue a network request if needed or just read
537 // from the cache if the cache entry is already valid. 551 // from the cache if the cache entry is already valid.
538 // 552 //
539 int rv; 553 int rv;
540 entry_ = entry; 554 entry_ = entry;
555 is_waiting_for_entry_ = false;
541 switch (mode_) { 556 switch (mode_) {
542 case READ: 557 case READ:
543 rv = BeginCacheRead(); 558 rv = BeginCacheRead();
544 break; 559 break;
545 case WRITE: 560 case WRITE:
546 rv = BeginNetworkRequest(); 561 rv = BeginNetworkRequest();
547 break; 562 break;
548 case READ_WRITE: 563 case READ_WRITE:
549 rv = BeginCacheValidation(); 564 rv = BeginCacheValidation();
550 break; 565 break;
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 958
944 if (result > 0) { 959 if (result > 0) {
945 read_offset_ += result; 960 read_offset_ += result;
946 } else if (result == 0) { // end of file 961 } else if (result == 0) { // end of file
947 cache_->DoneReadingFromEntry(entry_, this); 962 cache_->DoneReadingFromEntry(entry_, this);
948 entry_ = NULL; 963 entry_ = NULL;
949 } 964 }
950 HandleResult(result); 965 HandleResult(result);
951 } 966 }
952 967
968 void HttpCache::Transaction::PendOnEntry(ActiveEntry* entry) {
969 if (is_waiting_for_entry_) {
970 // Don't add timeout alarm more than once.
971 return;
972 }
973
974 is_waiting_for_entry_ = true;
975
976 MessageLoop::current()->PostDelayedTask(
977 FROM_HERE,
978 task_factory_.NewRunnableMethod(&Transaction::OnAddToEntryTimeout, entry),
979 kTransactionTimeoutInMillisecond);
980 }
981
982 void HttpCache::Transaction::OnAddToEntryTimeout(ActiveEntry* entry) {
983 if (!is_waiting_for_entry_) {
984 // Already added to entry.
985 return;
986 }
987
988 if (mode_ == READ) {
989 // We cannot bypass the cache.
990 return;
991 }
992
993 // Check that the writer is still busy, and then give up accessing cache.
994 if (entry->writer &&
995 entry->writer->GetLoadState() == LOAD_STATE_WAITING_FOR_USER_ACTION) {
996 // There is a writer transaction suspended due to some error. Bypass
997 // cache if we can.
998 entry->pending_queue.remove(this);
999 mode_ = NONE;
1000 is_waiting_for_entry_ = false;
1001 BeginNetworkRequest();
1002 }
1003 }
1004
953 //----------------------------------------------------------------------------- 1005 //-----------------------------------------------------------------------------
954 1006
955 HttpCache::HttpCache(ProxyService* proxy_service, 1007 HttpCache::HttpCache(ProxyService* proxy_service,
956 const std::wstring& cache_dir, 1008 const std::wstring& cache_dir,
957 int cache_size) 1009 int cache_size)
958 : disk_cache_dir_(cache_dir), 1010 : disk_cache_dir_(cache_dir),
959 mode_(NORMAL), 1011 mode_(NORMAL),
960 type_(DISK_CACHE), 1012 type_(DISK_CACHE),
961 network_layer_(HttpNetworkLayer::CreateFactory(proxy_service)), 1013 network_layer_(HttpNetworkLayer::CreateFactory(proxy_service)),
962 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), 1014 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 // We implement a basic reader/writer lock for the disk cache entry. If 1362 // We implement a basic reader/writer lock for the disk cache entry. If
1311 // there is already a writer, then everyone has to wait for the writer to 1363 // there is already a writer, then everyone has to wait for the writer to
1312 // finish before they can access the cache entry. There can be multiple 1364 // finish before they can access the cache entry. There can be multiple
1313 // readers. 1365 // readers.
1314 // 1366 //
1315 // NOTE: If the transaction can only write, then the entry should not be in 1367 // NOTE: If the transaction can only write, then the entry should not be in
1316 // use (since any existing entry should have already been doomed). 1368 // use (since any existing entry should have already been doomed).
1317 1369
1318 if (entry->writer || entry->will_process_pending_queue) { 1370 if (entry->writer || entry->will_process_pending_queue) {
1319 entry->pending_queue.push_back(trans); 1371 entry->pending_queue.push_back(trans);
1372 trans->PendOnEntry(entry);
1373
1320 return ERR_IO_PENDING; 1374 return ERR_IO_PENDING;
1321 } 1375 }
1322 1376
1323 if (trans->mode() & Transaction::WRITE) { 1377 if (trans->mode() & Transaction::WRITE) {
1324 // transaction needs exclusive access to the entry 1378 // transaction needs exclusive access to the entry
1325 if (entry->readers.empty()) { 1379 if (entry->readers.empty()) {
1326 entry->writer = trans; 1380 entry->writer = trans;
1327 } else { 1381 } else {
1328 entry->pending_queue.push_back(trans); 1382 entry->pending_queue.push_back(trans);
1329 return ERR_IO_PENDING; 1383 return ERR_IO_PENDING;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 return; // have to wait 1511 return; // have to wait
1458 1512
1459 entry->pending_queue.erase(entry->pending_queue.begin()); 1513 entry->pending_queue.erase(entry->pending_queue.begin());
1460 1514
1461 AddTransactionToEntry(entry, next); 1515 AddTransactionToEntry(entry, next);
1462 } 1516 }
1463 1517
1464 //----------------------------------------------------------------------------- 1518 //-----------------------------------------------------------------------------
1465 1519
1466 } // namespace net 1520 } // namespace net
OLDNEW
« no previous file with comments | « net/base/load_states.h ('k') | net/http/http_network_transaction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698