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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 const base::FilePath& path, | 59 const base::FilePath& path, |
60 int max_bytes, | 60 int max_bytes, |
61 base::MessageLoopProxy* thread) | 61 base::MessageLoopProxy* thread) |
62 : type_(type), | 62 : type_(type), |
63 backend_type_(backend_type), | 63 backend_type_(backend_type), |
64 path_(path), | 64 path_(path), |
65 max_bytes_(max_bytes), | 65 max_bytes_(max_bytes), |
66 thread_(thread) { | 66 thread_(thread) { |
67 } | 67 } |
68 | 68 |
69 HttpCache::DefaultBackend::~DefaultBackend() {} | 69 HttpCache::DefaultBackend::~DefaultBackend() { |
| 70 } |
70 | 71 |
71 // static | 72 // static |
72 HttpCache::BackendFactory* HttpCache::DefaultBackend::InMemory(int max_bytes) { | 73 HttpCache::BackendFactory* HttpCache::DefaultBackend::InMemory(int max_bytes) { |
73 return new DefaultBackend(MEMORY_CACHE, net::CACHE_BACKEND_DEFAULT, | 74 return new DefaultBackend(MEMORY_CACHE, |
74 base::FilePath(), max_bytes, NULL); | 75 net::CACHE_BACKEND_DEFAULT, |
| 76 base::FilePath(), |
| 77 max_bytes, |
| 78 NULL); |
75 } | 79 } |
76 | 80 |
77 int HttpCache::DefaultBackend::CreateBackend( | 81 int HttpCache::DefaultBackend::CreateBackend( |
78 NetLog* net_log, scoped_ptr<disk_cache::Backend>* backend, | 82 NetLog* net_log, |
| 83 scoped_ptr<disk_cache::Backend>* backend, |
79 const CompletionCallback& callback) { | 84 const CompletionCallback& callback) { |
80 DCHECK_GE(max_bytes_, 0); | 85 DCHECK_GE(max_bytes_, 0); |
81 return disk_cache::CreateCacheBackend(type_, | 86 return disk_cache::CreateCacheBackend(type_, |
82 backend_type_, | 87 backend_type_, |
83 path_, | 88 path_, |
84 max_bytes_, | 89 max_bytes_, |
85 true, | 90 true, |
86 thread_.get(), | 91 thread_.get(), |
87 net_log, | 92 net_log, |
88 backend, | 93 backend, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 WI_OPEN_ENTRY, | 133 WI_OPEN_ENTRY, |
129 WI_CREATE_ENTRY, | 134 WI_CREATE_ENTRY, |
130 WI_DOOM_ENTRY | 135 WI_DOOM_ENTRY |
131 }; | 136 }; |
132 | 137 |
133 // A work item encapsulates a single request to the backend with all the | 138 // A work item encapsulates a single request to the backend with all the |
134 // information needed to complete that request. | 139 // information needed to complete that request. |
135 class HttpCache::WorkItem { | 140 class HttpCache::WorkItem { |
136 public: | 141 public: |
137 WorkItem(WorkItemOperation operation, Transaction* trans, ActiveEntry** entry) | 142 WorkItem(WorkItemOperation operation, Transaction* trans, ActiveEntry** entry) |
138 : operation_(operation), | 143 : operation_(operation), trans_(trans), entry_(entry), backend_(NULL) {} |
139 trans_(trans), | 144 WorkItem(WorkItemOperation operation, |
140 entry_(entry), | 145 Transaction* trans, |
141 backend_(NULL) {} | 146 const net::CompletionCallback& cb, |
142 WorkItem(WorkItemOperation operation, Transaction* trans, | 147 disk_cache::Backend** backend) |
143 const net::CompletionCallback& cb, disk_cache::Backend** backend) | |
144 : operation_(operation), | 148 : operation_(operation), |
145 trans_(trans), | 149 trans_(trans), |
146 entry_(NULL), | 150 entry_(NULL), |
147 callback_(cb), | 151 callback_(cb), |
148 backend_(backend) {} | 152 backend_(backend) {} |
149 ~WorkItem() {} | 153 ~WorkItem() {} |
150 | 154 |
151 // Calls back the transaction with the result of the operation. | 155 // Calls back the transaction with the result of the operation. |
152 void NotifyTransaction(int result, ActiveEntry* entry) { | 156 void NotifyTransaction(int result, ActiveEntry* entry) { |
153 DCHECK(!entry || entry->disk_entry); | 157 DCHECK(!entry || entry->disk_entry); |
(...skipping 30 matching lines...) Expand all Loading... |
184 disk_cache::Backend** backend_; | 188 disk_cache::Backend** backend_; |
185 }; | 189 }; |
186 | 190 |
187 //----------------------------------------------------------------------------- | 191 //----------------------------------------------------------------------------- |
188 | 192 |
189 // This class encapsulates a transaction whose only purpose is to write metadata | 193 // This class encapsulates a transaction whose only purpose is to write metadata |
190 // to a given entry. | 194 // to a given entry. |
191 class HttpCache::MetadataWriter { | 195 class HttpCache::MetadataWriter { |
192 public: | 196 public: |
193 explicit MetadataWriter(HttpCache::Transaction* trans) | 197 explicit MetadataWriter(HttpCache::Transaction* trans) |
194 : transaction_(trans), | 198 : transaction_(trans), verified_(false), buf_len_(0) {} |
195 verified_(false), | |
196 buf_len_(0) { | |
197 } | |
198 | 199 |
199 ~MetadataWriter() {} | 200 ~MetadataWriter() {} |
200 | 201 |
201 // Implements the bulk of HttpCache::WriteMetadata. | 202 // Implements the bulk of HttpCache::WriteMetadata. |
202 void Write(const GURL& url, base::Time expected_response_time, IOBuffer* buf, | 203 void Write(const GURL& url, |
| 204 base::Time expected_response_time, |
| 205 IOBuffer* buf, |
203 int buf_len); | 206 int buf_len); |
204 | 207 |
205 private: | 208 private: |
206 void VerifyResponse(int result); | 209 void VerifyResponse(int result); |
207 void SelfDestroy(); | 210 void SelfDestroy(); |
208 void OnIOComplete(int result); | 211 void OnIOComplete(int result); |
209 | 212 |
210 scoped_ptr<HttpCache::Transaction> transaction_; | 213 scoped_ptr<HttpCache::Transaction> transaction_; |
211 bool verified_; | 214 bool verified_; |
212 scoped_refptr<IOBuffer> buf_; | 215 scoped_refptr<IOBuffer> buf_; |
213 int buf_len_; | 216 int buf_len_; |
214 base::Time expected_response_time_; | 217 base::Time expected_response_time_; |
215 HttpRequestInfo request_info_; | 218 HttpRequestInfo request_info_; |
216 DISALLOW_COPY_AND_ASSIGN(MetadataWriter); | 219 DISALLOW_COPY_AND_ASSIGN(MetadataWriter); |
217 }; | 220 }; |
218 | 221 |
219 void HttpCache::MetadataWriter::Write(const GURL& url, | 222 void HttpCache::MetadataWriter::Write(const GURL& url, |
220 base::Time expected_response_time, | 223 base::Time expected_response_time, |
221 IOBuffer* buf, int buf_len) { | 224 IOBuffer* buf, |
| 225 int buf_len) { |
222 DCHECK_GT(buf_len, 0); | 226 DCHECK_GT(buf_len, 0); |
223 DCHECK(buf); | 227 DCHECK(buf); |
224 DCHECK(buf->data()); | 228 DCHECK(buf->data()); |
225 request_info_.url = url; | 229 request_info_.url = url; |
226 request_info_.method = "GET"; | 230 request_info_.method = "GET"; |
227 request_info_.load_flags = LOAD_ONLY_FROM_CACHE; | 231 request_info_.load_flags = LOAD_ONLY_FROM_CACHE; |
228 | 232 |
229 expected_response_time_ = expected_response_time; | 233 expected_response_time_ = expected_response_time; |
230 buf_ = buf; | 234 buf_ = buf; |
231 buf_len_ = buf_len; | 235 buf_len_ = buf_len; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 if (!verified_) | 269 if (!verified_) |
266 return VerifyResponse(result); | 270 return VerifyResponse(result); |
267 SelfDestroy(); | 271 SelfDestroy(); |
268 } | 272 } |
269 | 273 |
270 //----------------------------------------------------------------------------- | 274 //----------------------------------------------------------------------------- |
271 | 275 |
272 class HttpCache::QuicServerInfoFactoryAdaptor : public QuicServerInfoFactory { | 276 class HttpCache::QuicServerInfoFactoryAdaptor : public QuicServerInfoFactory { |
273 public: | 277 public: |
274 QuicServerInfoFactoryAdaptor(HttpCache* http_cache) | 278 QuicServerInfoFactoryAdaptor(HttpCache* http_cache) |
275 : http_cache_(http_cache) { | 279 : http_cache_(http_cache) {} |
276 } | |
277 | 280 |
278 virtual QuicServerInfo* GetForServer( | 281 virtual QuicServerInfo* GetForServer(const QuicServerId& server_id) OVERRIDE { |
279 const QuicServerId& server_id) OVERRIDE { | |
280 return new DiskCacheBasedQuicServerInfo(server_id, http_cache_); | 282 return new DiskCacheBasedQuicServerInfo(server_id, http_cache_); |
281 } | 283 } |
282 | 284 |
283 private: | 285 private: |
284 HttpCache* const http_cache_; | 286 HttpCache* const http_cache_; |
285 }; | 287 }; |
286 | 288 |
287 //----------------------------------------------------------------------------- | 289 //----------------------------------------------------------------------------- |
288 HttpCache::HttpCache(const net::HttpNetworkSession::Params& params, | 290 HttpCache::HttpCache(const net::HttpNetworkSession::Params& params, |
289 BackendFactory* backend_factory) | 291 BackendFactory* backend_factory) |
290 : net_log_(params.net_log), | 292 : net_log_(params.net_log), |
291 backend_factory_(backend_factory), | 293 backend_factory_(backend_factory), |
292 building_backend_(false), | 294 building_backend_(false), |
293 mode_(NORMAL), | 295 mode_(NORMAL), |
294 quic_server_info_factory_(params.enable_quic_persist_server_info ? | 296 quic_server_info_factory_(params.enable_quic_persist_server_info |
295 new QuicServerInfoFactoryAdaptor(this) : NULL), | 297 ? new QuicServerInfoFactoryAdaptor(this) |
| 298 : NULL), |
296 network_layer_(new HttpNetworkLayer(new HttpNetworkSession(params))) { | 299 network_layer_(new HttpNetworkLayer(new HttpNetworkSession(params))) { |
297 HttpNetworkSession* session = network_layer_->GetSession(); | 300 HttpNetworkSession* session = network_layer_->GetSession(); |
298 session->quic_stream_factory()->set_quic_server_info_factory( | 301 session->quic_stream_factory()->set_quic_server_info_factory( |
299 quic_server_info_factory_.get()); | 302 quic_server_info_factory_.get()); |
300 } | 303 } |
301 | 304 |
302 | |
303 // This call doesn't change the shared |session|'s QuicServerInfoFactory because | 305 // This call doesn't change the shared |session|'s QuicServerInfoFactory because |
304 // |session| is shared. | 306 // |session| is shared. |
305 HttpCache::HttpCache(HttpNetworkSession* session, | 307 HttpCache::HttpCache(HttpNetworkSession* session, |
306 BackendFactory* backend_factory) | 308 BackendFactory* backend_factory) |
307 : net_log_(session->net_log()), | 309 : net_log_(session->net_log()), |
308 backend_factory_(backend_factory), | 310 backend_factory_(backend_factory), |
309 building_backend_(false), | 311 building_backend_(false), |
310 mode_(NORMAL), | 312 mode_(NORMAL), |
311 network_layer_(new HttpNetworkLayer(session)) { | 313 network_layer_(new HttpNetworkLayer(session)) { |
312 } | 314 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 } | 377 } |
376 | 378 |
377 return CreateBackend(backend, callback); | 379 return CreateBackend(backend, callback); |
378 } | 380 } |
379 | 381 |
380 disk_cache::Backend* HttpCache::GetCurrentBackend() const { | 382 disk_cache::Backend* HttpCache::GetCurrentBackend() const { |
381 return disk_cache_.get(); | 383 return disk_cache_.get(); |
382 } | 384 } |
383 | 385 |
384 // static | 386 // static |
385 bool HttpCache::ParseResponseInfo(const char* data, int len, | 387 bool HttpCache::ParseResponseInfo(const char* data, |
| 388 int len, |
386 HttpResponseInfo* response_info, | 389 HttpResponseInfo* response_info, |
387 bool* response_truncated) { | 390 bool* response_truncated) { |
388 Pickle pickle(data, len); | 391 Pickle pickle(data, len); |
389 return response_info->InitFromPickle(pickle, response_truncated); | 392 return response_info->InitFromPickle(pickle, response_truncated); |
390 } | 393 } |
391 | 394 |
392 void HttpCache::WriteMetadata(const GURL& url, | 395 void HttpCache::WriteMetadata(const GURL& url, |
393 RequestPriority priority, | 396 RequestPriority priority, |
394 base::Time expected_response_time, | 397 base::Time expected_response_time, |
395 IOBuffer* buf, | 398 IOBuffer* buf, |
396 int buf_len) { | 399 int buf_len) { |
397 if (!buf_len) | 400 if (!buf_len) |
398 return; | 401 return; |
399 | 402 |
400 // Do lazy initialization of disk cache if needed. | 403 // Do lazy initialization of disk cache if needed. |
401 if (!disk_cache_.get()) { | 404 if (!disk_cache_.get()) { |
402 // We don't care about the result. | 405 // We don't care about the result. |
403 CreateBackend(NULL, net::CompletionCallback()); | 406 CreateBackend(NULL, net::CompletionCallback()); |
404 } | 407 } |
405 | 408 |
406 HttpCache::Transaction* trans = | 409 HttpCache::Transaction* trans = new HttpCache::Transaction(priority, this); |
407 new HttpCache::Transaction(priority, this); | |
408 MetadataWriter* writer = new MetadataWriter(trans); | 410 MetadataWriter* writer = new MetadataWriter(trans); |
409 | 411 |
410 // The writer will self destruct when done. | 412 // The writer will self destruct when done. |
411 writer->Write(url, expected_response_time, buf, buf_len); | 413 writer->Write(url, expected_response_time, buf, buf_len); |
412 } | 414 } |
413 | 415 |
414 void HttpCache::CloseAllConnections() { | 416 void HttpCache::CloseAllConnections() { |
415 net::HttpNetworkLayer* network = | 417 net::HttpNetworkLayer* network = |
416 static_cast<net::HttpNetworkLayer*>(network_layer_.get()); | 418 static_cast<net::HttpNetworkLayer*>(network_layer_.get()); |
417 HttpNetworkSession* session = network->GetSession(); | 419 HttpNetworkSession* session = network->GetSession(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 | 479 |
478 //----------------------------------------------------------------------------- | 480 //----------------------------------------------------------------------------- |
479 | 481 |
480 int HttpCache::CreateBackend(disk_cache::Backend** backend, | 482 int HttpCache::CreateBackend(disk_cache::Backend** backend, |
481 const net::CompletionCallback& callback) { | 483 const net::CompletionCallback& callback) { |
482 if (!backend_factory_.get()) | 484 if (!backend_factory_.get()) |
483 return ERR_FAILED; | 485 return ERR_FAILED; |
484 | 486 |
485 building_backend_ = true; | 487 building_backend_ = true; |
486 | 488 |
487 scoped_ptr<WorkItem> item(new WorkItem(WI_CREATE_BACKEND, NULL, callback, | 489 scoped_ptr<WorkItem> item( |
488 backend)); | 490 new WorkItem(WI_CREATE_BACKEND, NULL, callback, backend)); |
489 | 491 |
490 // This is the only operation that we can do that is not related to any given | 492 // This is the only operation that we can do that is not related to any given |
491 // entry, so we use an empty key for it. | 493 // entry, so we use an empty key for it. |
492 PendingOp* pending_op = GetPendingOp(std::string()); | 494 PendingOp* pending_op = GetPendingOp(std::string()); |
493 if (pending_op->writer) { | 495 if (pending_op->writer) { |
494 if (!callback.is_null()) | 496 if (!callback.is_null()) |
495 pending_op->pending_queue.push_back(item.release()); | 497 pending_op->pending_queue.push_back(item.release()); |
496 return ERR_IO_PENDING; | 498 return ERR_IO_PENDING; |
497 } | 499 } |
498 | 500 |
499 DCHECK(pending_op->pending_queue.empty()); | 501 DCHECK(pending_op->pending_queue.empty()); |
500 | 502 |
501 pending_op->writer = item.release(); | 503 pending_op->writer = item.release(); |
502 pending_op->callback = base::Bind(&HttpCache::OnPendingOpComplete, | 504 pending_op->callback = |
503 AsWeakPtr(), pending_op); | 505 base::Bind(&HttpCache::OnPendingOpComplete, AsWeakPtr(), pending_op); |
504 | 506 |
505 int rv = backend_factory_->CreateBackend(net_log_, &pending_op->backend, | 507 int rv = backend_factory_->CreateBackend( |
506 pending_op->callback); | 508 net_log_, &pending_op->backend, pending_op->callback); |
507 if (rv != ERR_IO_PENDING) { | 509 if (rv != ERR_IO_PENDING) { |
508 pending_op->writer->ClearCallback(); | 510 pending_op->writer->ClearCallback(); |
509 pending_op->callback.Run(rv); | 511 pending_op->callback.Run(rv); |
510 } | 512 } |
511 | 513 |
512 return rv; | 514 return rv; |
513 } | 515 } |
514 | 516 |
515 int HttpCache::GetBackendForTransaction(Transaction* trans) { | 517 int HttpCache::GetBackendForTransaction(Transaction* trans) { |
516 if (disk_cache_.get()) | 518 if (disk_cache_.get()) |
517 return OK; | 519 return OK; |
518 | 520 |
519 if (!building_backend_) | 521 if (!building_backend_) |
520 return ERR_FAILED; | 522 return ERR_FAILED; |
521 | 523 |
522 WorkItem* item = new WorkItem( | 524 WorkItem* item = |
523 WI_CREATE_BACKEND, trans, net::CompletionCallback(), NULL); | 525 new WorkItem(WI_CREATE_BACKEND, trans, net::CompletionCallback(), NULL); |
524 PendingOp* pending_op = GetPendingOp(std::string()); | 526 PendingOp* pending_op = GetPendingOp(std::string()); |
525 DCHECK(pending_op->writer); | 527 DCHECK(pending_op->writer); |
526 pending_op->pending_queue.push_back(item); | 528 pending_op->pending_queue.push_back(item); |
527 return ERR_IO_PENDING; | 529 return ERR_IO_PENDING; |
528 } | 530 } |
529 | 531 |
530 // Generate a key that can be used inside the cache. | 532 // Generate a key that can be used inside the cache. |
531 std::string HttpCache::GenerateCacheKey(const HttpRequestInfo* request) { | 533 std::string HttpCache::GenerateCacheKey(const HttpRequestInfo* request) { |
532 // Strip out the reference, username, and password sections of the URL. | 534 // Strip out the reference, username, and password sections of the URL. |
533 std::string url = HttpUtil::SpecForRequest(request->url); | 535 std::string url = HttpUtil::SpecForRequest(request->url); |
534 | 536 |
535 DCHECK(mode_ != DISABLE); | 537 DCHECK(mode_ != DISABLE); |
536 if (mode_ == NORMAL) { | 538 if (mode_ == NORMAL) { |
537 // No valid URL can begin with numerals, so we should not have to worry | 539 // No valid URL can begin with numerals, so we should not have to worry |
538 // about collisions with normal URLs. | 540 // about collisions with normal URLs. |
539 if (request->upload_data_stream && | 541 if (request->upload_data_stream && |
540 request->upload_data_stream->identifier()) { | 542 request->upload_data_stream->identifier()) { |
541 url.insert(0, base::StringPrintf( | 543 url.insert(0, |
542 "%" PRId64 "/", request->upload_data_stream->identifier())); | 544 base::StringPrintf("%" PRId64 "/", |
| 545 request->upload_data_stream->identifier())); |
543 } | 546 } |
544 return url; | 547 return url; |
545 } | 548 } |
546 | 549 |
547 // In playback and record mode, we cache everything. | 550 // In playback and record mode, we cache everything. |
548 | 551 |
549 // Lazily initialize. | 552 // Lazily initialize. |
550 if (playback_cache_map_ == NULL) | 553 if (playback_cache_map_ == NULL) |
551 playback_cache_map_.reset(new PlaybackCacheMap()); | 554 playback_cache_map_.reset(new PlaybackCacheMap()); |
552 | 555 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 WorkItem* item = new WorkItem(WI_DOOM_ENTRY, trans, NULL); | 610 WorkItem* item = new WorkItem(WI_DOOM_ENTRY, trans, NULL); |
608 PendingOp* pending_op = GetPendingOp(key); | 611 PendingOp* pending_op = GetPendingOp(key); |
609 if (pending_op->writer) { | 612 if (pending_op->writer) { |
610 pending_op->pending_queue.push_back(item); | 613 pending_op->pending_queue.push_back(item); |
611 return ERR_IO_PENDING; | 614 return ERR_IO_PENDING; |
612 } | 615 } |
613 | 616 |
614 DCHECK(pending_op->pending_queue.empty()); | 617 DCHECK(pending_op->pending_queue.empty()); |
615 | 618 |
616 pending_op->writer = item; | 619 pending_op->writer = item; |
617 pending_op->callback = base::Bind(&HttpCache::OnPendingOpComplete, | 620 pending_op->callback = |
618 AsWeakPtr(), pending_op); | 621 base::Bind(&HttpCache::OnPendingOpComplete, AsWeakPtr(), pending_op); |
619 | 622 |
620 int rv = disk_cache_->DoomEntry(key, pending_op->callback); | 623 int rv = disk_cache_->DoomEntry(key, pending_op->callback); |
621 if (rv != ERR_IO_PENDING) { | 624 if (rv != ERR_IO_PENDING) { |
622 item->ClearTransaction(); | 625 item->ClearTransaction(); |
623 pending_op->callback.Run(rv); | 626 pending_op->callback.Run(rv); |
624 } | 627 } |
625 | 628 |
626 return rv; | 629 return rv; |
627 } | 630 } |
628 | 631 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 DCHECK(it != active_entries_.end()); | 688 DCHECK(it != active_entries_.end()); |
686 DCHECK(it->second == entry); | 689 DCHECK(it->second == entry); |
687 | 690 |
688 active_entries_.erase(it); | 691 active_entries_.erase(it); |
689 delete entry; | 692 delete entry; |
690 } | 693 } |
691 | 694 |
692 // We don't know this entry's key so we have to find it without it. | 695 // We don't know this entry's key so we have to find it without it. |
693 void HttpCache::SlowDeactivateEntry(ActiveEntry* entry) { | 696 void HttpCache::SlowDeactivateEntry(ActiveEntry* entry) { |
694 for (ActiveEntriesMap::iterator it = active_entries_.begin(); | 697 for (ActiveEntriesMap::iterator it = active_entries_.begin(); |
695 it != active_entries_.end(); ++it) { | 698 it != active_entries_.end(); |
| 699 ++it) { |
696 if (it->second == entry) { | 700 if (it->second == entry) { |
697 active_entries_.erase(it); | 701 active_entries_.erase(it); |
698 delete entry; | 702 delete entry; |
699 break; | 703 break; |
700 } | 704 } |
701 } | 705 } |
702 } | 706 } |
703 | 707 |
704 HttpCache::PendingOp* HttpCache::GetPendingOp(const std::string& key) { | 708 HttpCache::PendingOp* HttpCache::GetPendingOp(const std::string& key) { |
705 DCHECK(!FindActiveEntry(key)); | 709 DCHECK(!FindActiveEntry(key)); |
(...skipping 11 matching lines...) Expand all Loading... |
717 std::string key; | 721 std::string key; |
718 if (pending_op->disk_entry) | 722 if (pending_op->disk_entry) |
719 key = pending_op->disk_entry->GetKey(); | 723 key = pending_op->disk_entry->GetKey(); |
720 | 724 |
721 if (!key.empty()) { | 725 if (!key.empty()) { |
722 PendingOpsMap::iterator it = pending_ops_.find(key); | 726 PendingOpsMap::iterator it = pending_ops_.find(key); |
723 DCHECK(it != pending_ops_.end()); | 727 DCHECK(it != pending_ops_.end()); |
724 pending_ops_.erase(it); | 728 pending_ops_.erase(it); |
725 } else { | 729 } else { |
726 for (PendingOpsMap::iterator it = pending_ops_.begin(); | 730 for (PendingOpsMap::iterator it = pending_ops_.begin(); |
727 it != pending_ops_.end(); ++it) { | 731 it != pending_ops_.end(); |
| 732 ++it) { |
728 if (it->second == pending_op) { | 733 if (it->second == pending_op) { |
729 pending_ops_.erase(it); | 734 pending_ops_.erase(it); |
730 break; | 735 break; |
731 } | 736 } |
732 } | 737 } |
733 } | 738 } |
734 DCHECK(pending_op->pending_queue.empty()); | 739 DCHECK(pending_op->pending_queue.empty()); |
735 | 740 |
736 delete pending_op; | 741 delete pending_op; |
737 } | 742 } |
738 | 743 |
739 int HttpCache::OpenEntry(const std::string& key, ActiveEntry** entry, | 744 int HttpCache::OpenEntry(const std::string& key, |
| 745 ActiveEntry** entry, |
740 Transaction* trans) { | 746 Transaction* trans) { |
741 ActiveEntry* active_entry = FindActiveEntry(key); | 747 ActiveEntry* active_entry = FindActiveEntry(key); |
742 if (active_entry) { | 748 if (active_entry) { |
743 *entry = active_entry; | 749 *entry = active_entry; |
744 return OK; | 750 return OK; |
745 } | 751 } |
746 | 752 |
747 WorkItem* item = new WorkItem(WI_OPEN_ENTRY, trans, entry); | 753 WorkItem* item = new WorkItem(WI_OPEN_ENTRY, trans, entry); |
748 PendingOp* pending_op = GetPendingOp(key); | 754 PendingOp* pending_op = GetPendingOp(key); |
749 if (pending_op->writer) { | 755 if (pending_op->writer) { |
750 pending_op->pending_queue.push_back(item); | 756 pending_op->pending_queue.push_back(item); |
751 return ERR_IO_PENDING; | 757 return ERR_IO_PENDING; |
752 } | 758 } |
753 | 759 |
754 DCHECK(pending_op->pending_queue.empty()); | 760 DCHECK(pending_op->pending_queue.empty()); |
755 | 761 |
756 pending_op->writer = item; | 762 pending_op->writer = item; |
757 pending_op->callback = base::Bind(&HttpCache::OnPendingOpComplete, | 763 pending_op->callback = |
758 AsWeakPtr(), pending_op); | 764 base::Bind(&HttpCache::OnPendingOpComplete, AsWeakPtr(), pending_op); |
759 | 765 |
760 int rv = disk_cache_->OpenEntry(key, &(pending_op->disk_entry), | 766 int rv = disk_cache_->OpenEntry( |
761 pending_op->callback); | 767 key, &(pending_op->disk_entry), pending_op->callback); |
762 if (rv != ERR_IO_PENDING) { | 768 if (rv != ERR_IO_PENDING) { |
763 item->ClearTransaction(); | 769 item->ClearTransaction(); |
764 pending_op->callback.Run(rv); | 770 pending_op->callback.Run(rv); |
765 } | 771 } |
766 | 772 |
767 return rv; | 773 return rv; |
768 } | 774 } |
769 | 775 |
770 int HttpCache::CreateEntry(const std::string& key, ActiveEntry** entry, | 776 int HttpCache::CreateEntry(const std::string& key, |
| 777 ActiveEntry** entry, |
771 Transaction* trans) { | 778 Transaction* trans) { |
772 if (FindActiveEntry(key)) { | 779 if (FindActiveEntry(key)) { |
773 return ERR_CACHE_RACE; | 780 return ERR_CACHE_RACE; |
774 } | 781 } |
775 | 782 |
776 WorkItem* item = new WorkItem(WI_CREATE_ENTRY, trans, entry); | 783 WorkItem* item = new WorkItem(WI_CREATE_ENTRY, trans, entry); |
777 PendingOp* pending_op = GetPendingOp(key); | 784 PendingOp* pending_op = GetPendingOp(key); |
778 if (pending_op->writer) { | 785 if (pending_op->writer) { |
779 pending_op->pending_queue.push_back(item); | 786 pending_op->pending_queue.push_back(item); |
780 return ERR_IO_PENDING; | 787 return ERR_IO_PENDING; |
781 } | 788 } |
782 | 789 |
783 DCHECK(pending_op->pending_queue.empty()); | 790 DCHECK(pending_op->pending_queue.empty()); |
784 | 791 |
785 pending_op->writer = item; | 792 pending_op->writer = item; |
786 pending_op->callback = base::Bind(&HttpCache::OnPendingOpComplete, | 793 pending_op->callback = |
787 AsWeakPtr(), pending_op); | 794 base::Bind(&HttpCache::OnPendingOpComplete, AsWeakPtr(), pending_op); |
788 | 795 |
789 int rv = disk_cache_->CreateEntry(key, &(pending_op->disk_entry), | 796 int rv = disk_cache_->CreateEntry( |
790 pending_op->callback); | 797 key, &(pending_op->disk_entry), pending_op->callback); |
791 if (rv != ERR_IO_PENDING) { | 798 if (rv != ERR_IO_PENDING) { |
792 item->ClearTransaction(); | 799 item->ClearTransaction(); |
793 pending_op->callback.Run(rv); | 800 pending_op->callback.Run(rv); |
794 } | 801 } |
795 | 802 |
796 return rv; | 803 return rv; |
797 } | 804 } |
798 | 805 |
799 void HttpCache::DestroyEntry(ActiveEntry* entry) { | 806 void HttpCache::DestroyEntry(ActiveEntry* entry) { |
800 if (entry->doomed) { | 807 if (entry->doomed) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 | 843 |
837 // We do this before calling EntryAvailable to force any further calls to | 844 // We do this before calling EntryAvailable to force any further calls to |
838 // AddTransactionToEntry to add their transaction to the pending queue, which | 845 // AddTransactionToEntry to add their transaction to the pending queue, which |
839 // ensures FIFO ordering. | 846 // ensures FIFO ordering. |
840 if (!entry->writer && !entry->pending_queue.empty()) | 847 if (!entry->writer && !entry->pending_queue.empty()) |
841 ProcessPendingQueue(entry); | 848 ProcessPendingQueue(entry); |
842 | 849 |
843 return OK; | 850 return OK; |
844 } | 851 } |
845 | 852 |
846 void HttpCache::DoneWithEntry(ActiveEntry* entry, Transaction* trans, | 853 void HttpCache::DoneWithEntry(ActiveEntry* entry, |
| 854 Transaction* trans, |
847 bool cancel) { | 855 bool cancel) { |
848 // If we already posted a task to move on to the next transaction and this was | 856 // If we already posted a task to move on to the next transaction and this was |
849 // the writer, there is nothing to cancel. | 857 // the writer, there is nothing to cancel. |
850 if (entry->will_process_pending_queue && entry->readers.empty()) | 858 if (entry->will_process_pending_queue && entry->readers.empty()) |
851 return; | 859 return; |
852 | 860 |
853 if (entry->writer) { | 861 if (entry->writer) { |
854 DCHECK(trans == entry->writer); | 862 DCHECK(trans == entry->writer); |
855 | 863 |
856 // Assume there was a failure. | 864 // Assume there was a failure. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 | 924 |
917 Transaction* trans = entry->writer; | 925 Transaction* trans = entry->writer; |
918 | 926 |
919 entry->writer = NULL; | 927 entry->writer = NULL; |
920 entry->readers.push_back(trans); | 928 entry->readers.push_back(trans); |
921 | 929 |
922 ProcessPendingQueue(entry); | 930 ProcessPendingQueue(entry); |
923 } | 931 } |
924 | 932 |
925 LoadState HttpCache::GetLoadStateForPendingTransaction( | 933 LoadState HttpCache::GetLoadStateForPendingTransaction( |
926 const Transaction* trans) { | 934 const Transaction* trans) { |
927 ActiveEntriesMap::const_iterator i = active_entries_.find(trans->key()); | 935 ActiveEntriesMap::const_iterator i = active_entries_.find(trans->key()); |
928 if (i == active_entries_.end()) { | 936 if (i == active_entries_.end()) { |
929 // If this is really a pending transaction, and it is not part of | 937 // If this is really a pending transaction, and it is not part of |
930 // active_entries_, we should be creating the backend or the entry. | 938 // active_entries_, we should be creating the backend or the entry. |
931 return LOAD_STATE_WAITING_FOR_CACHE; | 939 return LOAD_STATE_WAITING_FOR_CACHE; |
932 } | 940 } |
933 | 941 |
934 Transaction* writer = i->second->writer; | 942 Transaction* writer = i->second->writer; |
935 return writer ? writer->GetWriterLoadState() : LOAD_STATE_WAITING_FOR_CACHE; | 943 return writer ? writer->GetWriterLoadState() : LOAD_STATE_WAITING_FOR_CACHE; |
936 } | 944 } |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1173 building_backend_ = false; | 1181 building_backend_ = false; |
1174 DeletePendingOp(pending_op); | 1182 DeletePendingOp(pending_op); |
1175 } | 1183 } |
1176 | 1184 |
1177 // The cache may be gone when we return from the callback. | 1185 // The cache may be gone when we return from the callback. |
1178 if (!item->DoCallback(result, disk_cache_.get())) | 1186 if (!item->DoCallback(result, disk_cache_.get())) |
1179 item->NotifyTransaction(result, NULL); | 1187 item->NotifyTransaction(result, NULL); |
1180 } | 1188 } |
1181 | 1189 |
1182 } // namespace net | 1190 } // namespace net |
OLD | NEW |