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 |