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

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

Issue 3108040: Merge 56964 - Http cache: It turns out that the cache destructor... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/472/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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 // Calls back the transaction with the result of the operation. 97 // Calls back the transaction with the result of the operation.
98 void NotifyTransaction(int result, ActiveEntry* entry) { 98 void NotifyTransaction(int result, ActiveEntry* entry) {
99 // TODO(rvargas): convert to DCHECK after fixing bug 47895. 99 // TODO(rvargas): convert to DCHECK after fixing bug 47895.
100 CHECK(!entry || entry->disk_entry); 100 CHECK(!entry || entry->disk_entry);
101 if (entry_) 101 if (entry_)
102 *entry_ = entry; 102 *entry_ = entry;
103 if (trans_) 103 if (trans_)
104 trans_->io_callback()->Run(result); 104 trans_->io_callback()->Run(result);
105 } 105 }
106 106
107 // Notifies the caller about the operation completion. 107 // Notifies the caller about the operation completion. Returns true if the
108 void DoCallback(int result, disk_cache::Backend* backend) { 108 // callback was invoked.
109 bool DoCallback(int result, disk_cache::Backend* backend) {
109 if (backend_) 110 if (backend_)
110 *backend_ = backend; 111 *backend_ = backend;
111 if (callback_) 112 if (callback_) {
112 callback_->Run(result); 113 callback_->Run(result);
114 return true;
115 }
116 return false;
113 } 117 }
114 118
115 WorkItemOperation operation() { return operation_; } 119 WorkItemOperation operation() { return operation_; }
116 void ClearTransaction() { trans_ = NULL; } 120 void ClearTransaction() { trans_ = NULL; }
117 void ClearEntry() { entry_ = NULL; } 121 void ClearEntry() { entry_ = NULL; }
118 void ClearCallback() { callback_ = NULL; } 122 void ClearCallback() { callback_ = NULL; }
119 bool Matches(Transaction* trans) const { return trans == trans_; } 123 bool Matches(Transaction* trans) const { return trans == trans_; }
120 bool IsValid() const { return trans_ || entry_ || callback_; } 124 bool IsValid() const { return trans_ || entry_ || callback_; }
121 125
122 private: 126 private:
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 for (; pending_it != pending_ops_.end(); ++pending_it) { 294 for (; pending_it != pending_ops_.end(); ++pending_it) {
291 // We are not notifying the transactions about the cache going away, even 295 // We are not notifying the transactions about the cache going away, even
292 // though they are waiting for a callback that will never fire. 296 // though they are waiting for a callback that will never fire.
293 PendingOp* pending_op = pending_it->second; 297 PendingOp* pending_op = pending_it->second;
294 delete pending_op->writer; 298 delete pending_op->writer;
295 if (building_backend_) { 299 if (building_backend_) {
296 // If we don't have a backend, when its construction finishes it will 300 // If we don't have a backend, when its construction finishes it will
297 // deliver the callbacks. 301 // deliver the callbacks.
298 BackendCallback* callback = 302 BackendCallback* callback =
299 static_cast<BackendCallback*>(pending_op->callback); 303 static_cast<BackendCallback*>(pending_op->callback);
300 callback->Cancel(); 304 if (callback)
305 callback->Cancel();
301 } else { 306 } else {
302 delete pending_op->callback; 307 delete pending_op->callback;
303 } 308 }
304 309
305 STLDeleteElements(&pending_op->pending_queue); 310 STLDeleteElements(&pending_op->pending_queue);
306 delete pending_op; 311 delete pending_op;
307 } 312 }
308 } 313 }
309 314
310 int HttpCache::GetBackend(disk_cache::Backend** backend, 315 int HttpCache::GetBackend(disk_cache::Backend** backend,
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 } 1005 }
1001 } 1006 }
1002 } 1007 }
1003 } 1008 }
1004 1009
1005 void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) { 1010 void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) {
1006 scoped_ptr<WorkItem> item(pending_op->writer); 1011 scoped_ptr<WorkItem> item(pending_op->writer);
1007 WorkItemOperation op = item->operation(); 1012 WorkItemOperation op = item->operation();
1008 DCHECK_EQ(WI_CREATE_BACKEND, op); 1013 DCHECK_EQ(WI_CREATE_BACKEND, op);
1009 1014
1010 backend_factory_.reset(); // Reclaim memory. 1015 // We don't need the callback anymore.
1016 pending_op->callback = NULL;
1011 1017
1012 if (result == OK) 1018 if (backend_factory_.get()) {
1013 disk_cache_.reset(temp_backend_); 1019 // We may end up calling OnBackendCreated multiple times if we have pending
1020 // work items. The first call saves the backend and releases the factory,
1021 // and the last call clears building_backend_.
1022 backend_factory_.reset(); // Reclaim memory.
1023 if (result == OK)
1024 disk_cache_.reset(temp_backend_);
1025 }
1014 1026
1015 item->DoCallback(result, temp_backend_); 1027 if (!pending_op->pending_queue.empty()) {
1016 1028 WorkItem* pending_item = pending_op->pending_queue.front();
1017 // Notify all callers and delete all pending work items.
1018 while (!pending_op->pending_queue.empty()) {
1019 scoped_ptr<WorkItem> pending_item(pending_op->pending_queue.front());
1020 pending_op->pending_queue.pop_front(); 1029 pending_op->pending_queue.pop_front();
1021 DCHECK_EQ(WI_CREATE_BACKEND, pending_item->operation()); 1030 DCHECK_EQ(WI_CREATE_BACKEND, pending_item->operation());
1022 1031
1023 // This could be an external caller or a transaction waiting on Start(). 1032 // We want to process a single callback at a time, because the cache may
1024 pending_item->DoCallback(result, temp_backend_); 1033 // go away from the callback.
1025 pending_item->NotifyTransaction(result, NULL); 1034 pending_op->writer = pending_item;
1035
1036 MessageLoop::current()->PostTask(
1037 FROM_HERE,
1038 task_factory_.NewRunnableMethod(&HttpCache::OnBackendCreated,
1039 result, pending_op));
1040 } else {
1041 building_backend_ = false;
1042 DeletePendingOp(pending_op);
1026 } 1043 }
1027 1044
1028 DeletePendingOp(pending_op); 1045 // The cache may be gone when we return from the callback.
1029 building_backend_ = false; 1046 if (!item->DoCallback(result, temp_backend_))
1047 item->NotifyTransaction(result, NULL);
1030 } 1048 }
1031 1049
1032 } // namespace net 1050 } // 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