OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |