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

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

Issue 3173030: Http cache: It turns out that the cache destructor... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 10 years, 4 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 | « no previous file | net/http/http_cache_unittest.cc » ('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) 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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | net/http/http_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698