| 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 |