Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 // Calls back the transaction with the result of the operation. | 98 // Calls back the transaction with the result of the operation. |
| 99 void NotifyTransaction(int result, ActiveEntry* entry) { | 99 void NotifyTransaction(int result, ActiveEntry* entry) { |
| 100 // TODO(rvargas): convert to DCHECK after fixing bug 47895. | 100 // TODO(rvargas): convert to DCHECK after fixing bug 47895. |
| 101 CHECK(!entry || entry->disk_entry); | 101 CHECK(!entry || entry->disk_entry); |
| 102 if (entry_) | 102 if (entry_) |
| 103 *entry_ = entry; | 103 *entry_ = entry; |
| 104 if (trans_) | 104 if (trans_) |
| 105 trans_->io_callback()->Run(result); | 105 trans_->io_callback()->Run(result); |
| 106 } | 106 } |
| 107 | 107 |
| 108 // Notifies the caller about the operation completion. | 108 // Notifies the caller about the operation completion. Returns true if the |
| 109 void DoCallback(int result, disk_cache::Backend* backend) { | 109 // callback was invoked. |
| 110 bool DoCallback(int result, disk_cache::Backend* backend) { | |
| 110 if (backend_) | 111 if (backend_) |
| 111 *backend_ = backend; | 112 *backend_ = backend; |
| 112 if (callback_) | 113 if (callback_) { |
| 113 callback_->Run(result); | 114 callback_->Run(result); |
| 115 return true; | |
| 116 } | |
| 117 return false; | |
| 114 } | 118 } |
| 115 | 119 |
| 116 WorkItemOperation operation() { return operation_; } | 120 WorkItemOperation operation() { return operation_; } |
| 117 void ClearTransaction() { trans_ = NULL; } | 121 void ClearTransaction() { trans_ = NULL; } |
| 118 void ClearEntry() { entry_ = NULL; } | 122 void ClearEntry() { entry_ = NULL; } |
| 119 void ClearCallback() { callback_ = NULL; } | 123 void ClearCallback() { callback_ = NULL; } |
| 120 bool Matches(Transaction* trans) const { return trans == trans_; } | 124 bool Matches(Transaction* trans) const { return trans == trans_; } |
| 121 bool IsValid() const { return trans_ || entry_ || callback_; } | 125 bool IsValid() const { return trans_ || entry_ || callback_; } |
| 122 | 126 |
| 123 private: | 127 private: |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 for (; pending_it != pending_ops_.end(); ++pending_it) { | 295 for (; pending_it != pending_ops_.end(); ++pending_it) { |
| 292 // We are not notifying the transactions about the cache going away, even | 296 // We are not notifying the transactions about the cache going away, even |
| 293 // though they are waiting for a callback that will never fire. | 297 // though they are waiting for a callback that will never fire. |
| 294 PendingOp* pending_op = pending_it->second; | 298 PendingOp* pending_op = pending_it->second; |
| 295 delete pending_op->writer; | 299 delete pending_op->writer; |
| 296 if (building_backend_) { | 300 if (building_backend_) { |
| 297 // If we don't have a backend, when its construction finishes it will | 301 // If we don't have a backend, when its construction finishes it will |
| 298 // deliver the callbacks. | 302 // deliver the callbacks. |
| 299 BackendCallback* callback = | 303 BackendCallback* callback = |
| 300 static_cast<BackendCallback*>(pending_op->callback); | 304 static_cast<BackendCallback*>(pending_op->callback); |
| 301 callback->Cancel(); | 305 if (callback) |
| 306 callback->Cancel(); | |
| 302 } else { | 307 } else { |
| 303 delete pending_op->callback; | 308 delete pending_op->callback; |
| 304 } | 309 } |
| 305 | 310 |
| 306 STLDeleteElements(&pending_op->pending_queue); | 311 STLDeleteElements(&pending_op->pending_queue); |
| 307 delete pending_op; | 312 delete pending_op; |
| 308 } | 313 } |
| 309 } | 314 } |
| 310 | 315 |
| 311 int HttpCache::GetBackend(disk_cache::Backend** backend, | 316 int HttpCache::GetBackend(disk_cache::Backend** backend, |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1002 } | 1007 } |
| 1003 } | 1008 } |
| 1004 } | 1009 } |
| 1005 } | 1010 } |
| 1006 | 1011 |
| 1007 void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) { | 1012 void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) { |
| 1008 scoped_ptr<WorkItem> item(pending_op->writer); | 1013 scoped_ptr<WorkItem> item(pending_op->writer); |
| 1009 WorkItemOperation op = item->operation(); | 1014 WorkItemOperation op = item->operation(); |
| 1010 DCHECK_EQ(WI_CREATE_BACKEND, op); | 1015 DCHECK_EQ(WI_CREATE_BACKEND, op); |
| 1011 | 1016 |
| 1012 backend_factory_.reset(); // Reclaim memory. | 1017 // We don't need the callback anymore. |
| 1018 pending_op->callback = NULL; | |
| 1013 | 1019 |
| 1014 if (result == OK) | 1020 if (backend_factory_.get()) { |
|
eroman
2010/08/20 18:15:23
Can you add a comment explaining this check is bec
rvargas (doing something else)
2010/08/20 18:47:38
Added:
// We may end up calling OnBackendCreated m
| |
| 1015 disk_cache_.reset(temp_backend_); | 1021 backend_factory_.reset(); // Reclaim memory. |
| 1022 if (result == OK) | |
| 1023 disk_cache_.reset(temp_backend_); | |
| 1024 } | |
| 1016 | 1025 |
| 1017 item->DoCallback(result, temp_backend_); | 1026 if (!pending_op->pending_queue.empty()) { |
| 1018 | 1027 WorkItem* pending_item = pending_op->pending_queue.front(); |
| 1019 // Notify all callers and delete all pending work items. | |
| 1020 while (!pending_op->pending_queue.empty()) { | |
| 1021 scoped_ptr<WorkItem> pending_item(pending_op->pending_queue.front()); | |
| 1022 pending_op->pending_queue.pop_front(); | 1028 pending_op->pending_queue.pop_front(); |
| 1023 DCHECK_EQ(WI_CREATE_BACKEND, pending_item->operation()); | 1029 DCHECK_EQ(WI_CREATE_BACKEND, pending_item->operation()); |
| 1024 | 1030 |
| 1025 // This could be an external caller or a transaction waiting on Start(). | 1031 // We want to process a single callback at a time, because the cache may |
| 1026 pending_item->DoCallback(result, temp_backend_); | 1032 // go away from the callback. |
| 1027 pending_item->NotifyTransaction(result, NULL); | 1033 pending_op->writer = pending_item; |
| 1034 | |
| 1035 MessageLoop::current()->PostTask( | |
| 1036 FROM_HERE, | |
| 1037 task_factory_.NewRunnableMethod(&HttpCache::OnBackendCreated, | |
| 1038 result, pending_op)); | |
|
eroman
2010/08/20 18:15:23
Won't this leak pending_op if HttpCache gets delet
rvargas (doing something else)
2010/08/20 18:47:38
No, it doesn't. pending_op is part of a list that
eroman
2010/08/20 18:56:38
Ah my bad. LGTM
| |
| 1039 } else { | |
| 1040 building_backend_ = false; | |
| 1041 DeletePendingOp(pending_op); | |
| 1028 } | 1042 } |
| 1029 | 1043 |
| 1030 DeletePendingOp(pending_op); | 1044 // The cache may be gone when we return from the callback. |
| 1031 building_backend_ = false; | 1045 if (!item->DoCallback(result, temp_backend_)) |
| 1046 item->NotifyTransaction(result, NULL); | |
| 1032 } | 1047 } |
| 1033 | 1048 |
| 1034 } // namespace net | 1049 } // namespace net |
| OLD | NEW |