| 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 |