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

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

Issue 155018: Add more code to debug a crash inside HttpCache::DeactivateEntry... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 5 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
« net/http/http_cache.h ('K') | « net/http/http_cache.h ('k') | no next file » | 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) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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 1241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 ProxyService* proxy_service, 1252 ProxyService* proxy_service,
1253 const std::wstring& cache_dir, 1253 const std::wstring& cache_dir,
1254 int cache_size) 1254 int cache_size)
1255 : disk_cache_dir_(cache_dir), 1255 : disk_cache_dir_(cache_dir),
1256 mode_(NORMAL), 1256 mode_(NORMAL),
1257 type_(DISK_CACHE), 1257 type_(DISK_CACHE),
1258 network_layer_(HttpNetworkLayer::CreateFactory( 1258 network_layer_(HttpNetworkLayer::CreateFactory(
1259 host_resolver, proxy_service)), 1259 host_resolver, proxy_service)),
1260 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), 1260 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
1261 in_memory_cache_(false), 1261 in_memory_cache_(false),
1262 deleted_(false),
1262 cache_size_(cache_size) { 1263 cache_size_(cache_size) {
1263 } 1264 }
1264 1265
1265 HttpCache::HttpCache(HttpNetworkSession* session, 1266 HttpCache::HttpCache(HttpNetworkSession* session,
1266 const std::wstring& cache_dir, 1267 const std::wstring& cache_dir,
1267 int cache_size) 1268 int cache_size)
1268 : disk_cache_dir_(cache_dir), 1269 : disk_cache_dir_(cache_dir),
1269 mode_(NORMAL), 1270 mode_(NORMAL),
1270 type_(DISK_CACHE), 1271 type_(DISK_CACHE),
1271 network_layer_(HttpNetworkLayer::CreateFactory(session)), 1272 network_layer_(HttpNetworkLayer::CreateFactory(session)),
1272 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), 1273 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
1273 in_memory_cache_(false), 1274 in_memory_cache_(false),
1275 deleted_(false),
1274 cache_size_(cache_size) { 1276 cache_size_(cache_size) {
1275 } 1277 }
1276 1278
1277 HttpCache::HttpCache(HostResolver* host_resolver, 1279 HttpCache::HttpCache(HostResolver* host_resolver,
1278 ProxyService* proxy_service, 1280 ProxyService* proxy_service,
1279 int cache_size) 1281 int cache_size)
1280 : mode_(NORMAL), 1282 : mode_(NORMAL),
1281 type_(MEMORY_CACHE), 1283 type_(MEMORY_CACHE),
1282 network_layer_(HttpNetworkLayer::CreateFactory( 1284 network_layer_(HttpNetworkLayer::CreateFactory(
1283 host_resolver, proxy_service)), 1285 host_resolver, proxy_service)),
1284 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), 1286 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
1285 in_memory_cache_(true), 1287 in_memory_cache_(true),
1288 deleted_(false),
1286 cache_size_(cache_size) { 1289 cache_size_(cache_size) {
1287 } 1290 }
1288 1291
1289 HttpCache::HttpCache(HttpTransactionFactory* network_layer, 1292 HttpCache::HttpCache(HttpTransactionFactory* network_layer,
1290 disk_cache::Backend* disk_cache) 1293 disk_cache::Backend* disk_cache)
1291 : mode_(NORMAL), 1294 : mode_(NORMAL),
1292 type_(DISK_CACHE), 1295 type_(DISK_CACHE),
1293 network_layer_(network_layer), 1296 network_layer_(network_layer),
1294 disk_cache_(disk_cache), 1297 disk_cache_(disk_cache),
1295 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), 1298 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
1296 in_memory_cache_(false), 1299 in_memory_cache_(false),
1300 deleted_(false),
1297 cache_size_(0) { 1301 cache_size_(0) {
1298 } 1302 }
1299 1303
1300 HttpCache::~HttpCache() { 1304 HttpCache::~HttpCache() {
1301 // If we have any active entries remaining, then we need to deactivate them. 1305 // If we have any active entries remaining, then we need to deactivate them.
1302 // We may have some pending calls to OnProcessPendingQueue, but since those 1306 // We may have some pending calls to OnProcessPendingQueue, but since those
1303 // won't run (due to our destruction), we can simply ignore the corresponding 1307 // won't run (due to our destruction), we can simply ignore the corresponding
1304 // will_process_pending_queue flag. 1308 // will_process_pending_queue flag.
1305 while (!active_entries_.empty()) { 1309 while (!active_entries_.empty()) {
1306 ActiveEntry* entry = active_entries_.begin()->second; 1310 ActiveEntry* entry = active_entries_.begin()->second;
1307 entry->will_process_pending_queue = false; 1311 entry->will_process_pending_queue = false;
1308 entry->pending_queue.clear(); 1312 entry->pending_queue.clear();
1309 entry->readers.clear(); 1313 entry->readers.clear();
1310 entry->writer = NULL; 1314 entry->writer = NULL;
1311 DeactivateEntry(entry); 1315 DeactivateEntry(entry);
1312 } 1316 }
1313 1317
1314 ActiveEntriesSet::iterator it = doomed_entries_.begin(); 1318 ActiveEntriesSet::iterator it = doomed_entries_.begin();
1315 for (; it != doomed_entries_.end(); ++it) 1319 for (; it != doomed_entries_.end(); ++it)
1316 delete *it; 1320 delete *it;
1321
1322 // TODO(rvargas): remove this. I'm just tracking a few crashes.
1323 deleted_ = true;
1317 } 1324 }
1318 1325
1319 HttpTransaction* HttpCache::CreateTransaction() { 1326 HttpTransaction* HttpCache::CreateTransaction() {
1320 // Do lazy initialization of disk cache if needed. 1327 // Do lazy initialization of disk cache if needed.
1321 if (!disk_cache_.get()) { 1328 if (!disk_cache_.get()) {
1322 DCHECK(cache_size_ >= 0); 1329 DCHECK(cache_size_ >= 0);
1323 if (in_memory_cache_) { 1330 if (in_memory_cache_) {
1324 // We may end up with no folder name and no cache if the initialization 1331 // We may end up with no folder name and no cache if the initialization
1325 // of the disk cache fails. We want to be sure that what we wanted to have 1332 // of the disk cache fails. We want to be sure that what we wanted to have
1326 // was an in-memory cache. 1333 // was an in-memory cache.
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 if (entry->doomed) { 1571 if (entry->doomed) {
1565 FinalizeDoomedEntry(entry); 1572 FinalizeDoomedEntry(entry);
1566 } else { 1573 } else {
1567 DeactivateEntry(entry); 1574 DeactivateEntry(entry);
1568 } 1575 }
1569 } 1576 }
1570 1577
1571 HttpCache::ActiveEntry* HttpCache::ActivateEntry( 1578 HttpCache::ActiveEntry* HttpCache::ActivateEntry(
1572 const std::string& key, 1579 const std::string& key,
1573 disk_cache::Entry* disk_entry) { 1580 disk_cache::Entry* disk_entry) {
1581 // TODO(rvargas): remove this code.
1582 ActiveEntriesMap::iterator it = active_entries_.find(key);
1583 CHECK(it == active_entries_.end());
1584
1574 ActiveEntry* entry = new ActiveEntry(disk_entry); 1585 ActiveEntry* entry = new ActiveEntry(disk_entry);
1575 active_entries_[key] = entry; 1586 active_entries_[key] = entry;
1576 return entry; 1587 return entry;
1577 } 1588 }
1578 1589
1579 #if defined(OS_WIN) 1590 #if defined(OS_WIN)
1580 #pragma optimize("", off) 1591 #pragma optimize("", off)
1581 #endif 1592 #endif
1582 // Avoid optimizing local_entry out of the code. 1593 // Avoid optimizing local_entry out of the code.
1583 void HttpCache::DeactivateEntry(ActiveEntry* entry) { 1594 void HttpCache::DeactivateEntry(ActiveEntry* entry) {
1584 // TODO(rvargas): remove this code and go back to DCHECKS once we find out 1595 // TODO(rvargas): remove this code and go back to DCHECKS once we find out
1585 // why are we crashing. I'm just trying to gather more info for bug 3931. 1596 // why are we crashing. I'm just trying to gather more info for bug 3931.
1586 ActiveEntry local_entry = *entry; 1597 ActiveEntry local_entry = *entry;
1587 size_t readers_size = local_entry.readers.size(); 1598 size_t readers_size = local_entry.readers.size();
1588 size_t pending_size = local_entry.pending_queue.size(); 1599 size_t pending_size = local_entry.pending_queue.size();
1589 1600
1590 ActiveEntriesMap::iterator it = 1601 ActiveEntriesMap::iterator it =
1591 active_entries_.find(entry->disk_entry->GetKey()); 1602 active_entries_.find(entry->disk_entry->GetKey());
1592 CHECK(it != active_entries_.end()); 1603 if (it == active_entries_.end() || it->second != entry ||
1593 CHECK(it->second == entry); 1604 local_entry.will_process_pending_queue || local_entry.doomed ||
1594 1605 local_entry.writer || readers_size || pending_size || deleted_) {
1595 if (local_entry.will_process_pending_queue || local_entry.doomed || 1606 bool local_mem_flag = in_memory_cache_;
1596 local_entry.writer || readers_size || pending_size) { 1607 ActiveEntriesSet::iterator it2 = doomed_entries_.find(entry);
1608 CHECK(it2 == doomed_entries_.end());
1609 CHECK(!deleted_);
1610 CHECK(local_mem_flag);
1597 CHECK(false); 1611 CHECK(false);
1598 } 1612 }
1599 1613
1600 active_entries_.erase(it); 1614 active_entries_.erase(it);
1601 delete entry; 1615 delete entry;
1602 1616
1603 // Avoid closing the disk_entry again on the destructor. 1617 // Avoid closing the disk_entry again on the destructor.
1604 local_entry.disk_entry = NULL; 1618 local_entry.disk_entry = NULL;
1605 } 1619 }
1606 #if defined(OS_WIN) 1620 #if defined(OS_WIN)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1638 1652
1639 // We do this before calling EntryAvailable to force any further calls to 1653 // We do this before calling EntryAvailable to force any further calls to
1640 // AddTransactionToEntry to add their transaction to the pending queue, which 1654 // AddTransactionToEntry to add their transaction to the pending queue, which
1641 // ensures FIFO ordering. 1655 // ensures FIFO ordering.
1642 if (!entry->writer && !entry->pending_queue.empty()) 1656 if (!entry->writer && !entry->pending_queue.empty())
1643 ProcessPendingQueue(entry); 1657 ProcessPendingQueue(entry);
1644 1658
1645 return trans->EntryAvailable(entry); 1659 return trans->EntryAvailable(entry);
1646 } 1660 }
1647 1661
1662 #if defined(OS_WIN)
1663 #pragma optimize("", off)
1664 #pragma warning(disable:4748)
1665 #endif
1666 // Avoid optimizing local_transaction out of the code.
1648 void HttpCache::DoneWithEntry(ActiveEntry* entry, Transaction* trans) { 1667 void HttpCache::DoneWithEntry(ActiveEntry* entry, Transaction* trans) {
1649 // If we already posted a task to move on to the next transaction and this was 1668 // If we already posted a task to move on to the next transaction and this was
1650 // the writer, there is nothing to cancel. 1669 // the writer, there is nothing to cancel.
1651 if (entry->will_process_pending_queue && entry->readers.empty()) 1670 if (entry->will_process_pending_queue && entry->readers.empty())
1652 return; 1671 return;
1653 1672
1654 if (entry->writer) { 1673 if (entry->writer) {
1655 // TODO(rvargas): convert this to a DCHECK. 1674 // TODO(rvargas): convert this to a DCHECK.
1656 CHECK(trans == entry->writer); 1675 CHECK(trans == entry->writer);
1676 // Get a local copy of the transaction, in preparation for a crash inside
1677 // DeactivateEntry.
1678 char local_transaction[sizeof(*trans)];
1679 memcpy(local_transaction, trans, sizeof(*trans));
1680
1657 // Assume that this is not a successful write. 1681 // Assume that this is not a successful write.
1658 DoneWritingToEntry(entry, false); 1682 DoneWritingToEntry(entry, false);
1659 } else { 1683 } else {
1660 DoneReadingFromEntry(entry, trans); 1684 DoneReadingFromEntry(entry, trans);
1661 } 1685 }
1662 } 1686 }
1687 #if defined(OS_WIN)
1688 #pragma warning(default:4748)
1689 #pragma optimize("", on)
1690 #endif
1663 1691
1664 void HttpCache::DoneWritingToEntry(ActiveEntry* entry, bool success) { 1692 void HttpCache::DoneWritingToEntry(ActiveEntry* entry, bool success) {
1665 DCHECK(entry->readers.empty()); 1693 DCHECK(entry->readers.empty());
1666 1694
1667 entry->writer = NULL; 1695 entry->writer = NULL;
1668 1696
1669 if (success) { 1697 if (success) {
1670 ProcessPendingQueue(entry); 1698 ProcessPendingQueue(entry);
1671 } else { 1699 } else {
1672 // TODO(rvargas): convert this to a DCHECK. 1700 // TODO(rvargas): convert this to a DCHECK.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 static_cast<net::HttpNetworkLayer*>(network_layer_.get()); 1797 static_cast<net::HttpNetworkLayer*>(network_layer_.get());
1770 HttpNetworkSession* session = network->GetSession(); 1798 HttpNetworkSession* session = network->GetSession();
1771 if (session) { 1799 if (session) {
1772 session->connection_pool()->CloseIdleSockets(); 1800 session->connection_pool()->CloseIdleSockets();
1773 } 1801 }
1774 } 1802 }
1775 1803
1776 //----------------------------------------------------------------------------- 1804 //-----------------------------------------------------------------------------
1777 1805
1778 } // namespace net 1806 } // namespace net
OLDNEW
« net/http/http_cache.h ('K') | « net/http/http_cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698