| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/disk_cache/backend_impl.h" | 5 #include "net/disk_cache/backend_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 disabled_(false), | 345 disabled_(false), |
| 346 new_eviction_(false), | 346 new_eviction_(false), |
| 347 first_timer_(true), | 347 first_timer_(true), |
| 348 user_load_(false), | 348 user_load_(false), |
| 349 net_log_(net_log), | 349 net_log_(net_log), |
| 350 done_(true, false), | 350 done_(true, false), |
| 351 ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) { | 351 ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) { |
| 352 } | 352 } |
| 353 | 353 |
| 354 BackendImpl::~BackendImpl() { | 354 BackendImpl::~BackendImpl() { |
| 355 background_queue_.WaitForPendingIO(); | 355 if (user_flags_ & kNoRandom) { |
| 356 // This is a unit test, so we want to be strict about not leaking entries |
| 357 // and completing all the work. |
| 358 background_queue_.WaitForPendingIO(); |
| 359 } else { |
| 360 // This is most likely not a test, so we want to do as little work as |
| 361 // possible at this time, at the price of leaving dirty entries behind. |
| 362 background_queue_.DropPendingIO(); |
| 363 } |
| 356 | 364 |
| 357 if (background_queue_.BackgroundIsCurrentThread()) { | 365 if (background_queue_.BackgroundIsCurrentThread()) { |
| 358 // Unit tests may use the same thread for everything. | 366 // Unit tests may use the same thread for everything. |
| 359 CleanupCache(); | 367 CleanupCache(); |
| 360 } else { | 368 } else { |
| 361 background_queue_.background_thread()->PostTask( | 369 background_queue_.background_thread()->PostTask( |
| 362 FROM_HERE, base::Bind(&FinalCleanupCallback, base::Unretained(this))); | 370 FROM_HERE, base::Bind(&FinalCleanupCallback, base::Unretained(this))); |
| 363 done_.Wait(); | 371 done_.Wait(); |
| 364 } | 372 } |
| 365 } | 373 } |
| 366 | 374 |
| 367 // If the initialization of the cache fails, and force is true, we will discard | 375 // If the initialization of the cache fails, and force is true, we will discard |
| 368 // the whole cache and create a new one. In order to process a potentially large | 376 // the whole cache and create a new one. In order to process a potentially large |
| 369 // number of files, we'll rename the cache folder to old_ + original_name + | 377 // number of files, we'll rename the cache folder to old_ + original_name + |
| 370 // number, (located on the same parent folder), and spawn a worker thread to | 378 // number, (located on the same parent folder), and spawn a worker thread to |
| 371 // delete all the files on all the stale cache folders. The whole process can | 379 // delete all the files on all the stale cache folders. The whole process can |
| 372 // still fail if we are not able to rename the cache folder (for instance due to | 380 // still fail if we are not able to rename the cache folder (for instance due to |
| 373 // a sharing violation), and in that case a cache for this profile (on the | 381 // a sharing violation), and in that case a cache for this profile (on the |
| 374 // desired path) cannot be created. | 382 // desired path) cannot be created. |
| 375 // | 383 // |
| 376 // Static. | 384 // Static. |
| 377 int BackendImpl::CreateBackend(const FilePath& full_path, bool force, | 385 int BackendImpl::CreateBackend(const FilePath& full_path, bool force, |
| 378 int max_bytes, net::CacheType type, | 386 int max_bytes, net::CacheType type, |
| 379 uint32 flags, base::MessageLoopProxy* thread, | 387 uint32 flags, base::MessageLoopProxy* thread, |
| 380 net::NetLog* net_log, Backend** backend, | 388 net::NetLog* net_log, Backend** backend, |
| 381 const net::CompletionCallback& callback) { | 389 const CompletionCallback& callback) { |
| 382 DCHECK(!callback.is_null()); | 390 DCHECK(!callback.is_null()); |
| 383 CacheCreator* creator = | 391 CacheCreator* creator = |
| 384 new CacheCreator(full_path, force, max_bytes, type, flags, thread, | 392 new CacheCreator(full_path, force, max_bytes, type, flags, thread, |
| 385 net_log, backend, callback); | 393 net_log, backend, callback); |
| 386 // This object will self-destroy when finished. | 394 // This object will self-destroy when finished. |
| 387 return creator->Run(); | 395 return creator->Run(); |
| 388 } | 396 } |
| 389 | 397 |
| 390 int BackendImpl::Init(const net::CompletionCallback& callback) { | 398 int BackendImpl::Init(const CompletionCallback& callback) { |
| 391 background_queue_.Init(callback); | 399 background_queue_.Init(callback); |
| 392 return net::ERR_IO_PENDING; | 400 return net::ERR_IO_PENDING; |
| 393 } | 401 } |
| 394 | 402 |
| 395 int BackendImpl::SyncInit() { | 403 int BackendImpl::SyncInit() { |
| 396 #if defined(NET_BUILD_STRESS_CACHE) | 404 #if defined(NET_BUILD_STRESS_CACHE) |
| 397 // Start evictions right away. | 405 // Start evictions right away. |
| 398 up_ticks_ = kTrimDelay * 2; | 406 up_ticks_ = kTrimDelay * 2; |
| 399 #endif | 407 #endif |
| 400 DCHECK(!init_); | 408 DCHECK(!init_); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 421 | 429 |
| 422 init_ = true; | 430 init_ = true; |
| 423 Trace("Init"); | 431 Trace("Init"); |
| 424 | 432 |
| 425 if (data_->header.experiment != NO_EXPERIMENT && | 433 if (data_->header.experiment != NO_EXPERIMENT && |
| 426 cache_type_ != net::DISK_CACHE) { | 434 cache_type_ != net::DISK_CACHE) { |
| 427 // No experiment for other caches. | 435 // No experiment for other caches. |
| 428 return net::ERR_FAILED; | 436 return net::ERR_FAILED; |
| 429 } | 437 } |
| 430 | 438 |
| 431 if (!(user_flags_ & disk_cache::kNoRandom)) { | 439 if (!(user_flags_ & kNoRandom)) { |
| 432 // The unit test controls directly what to test. | 440 // The unit test controls directly what to test. |
| 433 new_eviction_ = (cache_type_ == net::DISK_CACHE); | 441 new_eviction_ = (cache_type_ == net::DISK_CACHE); |
| 434 } | 442 } |
| 435 | 443 |
| 436 if (!CheckIndex()) { | 444 if (!CheckIndex()) { |
| 437 ReportError(ERR_INIT_FAILED); | 445 ReportError(ERR_INIT_FAILED); |
| 438 return net::ERR_FAILED; | 446 return net::ERR_FAILED; |
| 439 } | 447 } |
| 440 | 448 |
| 441 if (!(user_flags_ & disk_cache::kNoRandom) && | 449 if (!(user_flags_ & kNoRandom) && |
| 442 cache_type_ == net::DISK_CACHE && !InitExperiment(&data_->header)) | 450 cache_type_ == net::DISK_CACHE && !InitExperiment(&data_->header)) |
| 443 return net::ERR_FAILED; | 451 return net::ERR_FAILED; |
| 444 | 452 |
| 445 // We don't care if the value overflows. The only thing we care about is that | 453 // We don't care if the value overflows. The only thing we care about is that |
| 446 // the id cannot be zero, because that value is used as "not dirty". | 454 // the id cannot be zero, because that value is used as "not dirty". |
| 447 // Increasing the value once per second gives us many years before we start | 455 // Increasing the value once per second gives us many years before we start |
| 448 // having collisions. | 456 // having collisions. |
| 449 data_->header.this_id++; | 457 data_->header.this_id++; |
| 450 if (!data_->header.this_id) | 458 if (!data_->header.this_id) |
| 451 data_->header.this_id++; | 459 data_->header.this_id++; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 void BackendImpl::CleanupCache() { | 497 void BackendImpl::CleanupCache() { |
| 490 Trace("Backend Cleanup"); | 498 Trace("Backend Cleanup"); |
| 491 eviction_.Stop(); | 499 eviction_.Stop(); |
| 492 timer_.Stop(); | 500 timer_.Stop(); |
| 493 | 501 |
| 494 if (init_) { | 502 if (init_) { |
| 495 stats_.Store(); | 503 stats_.Store(); |
| 496 if (data_) | 504 if (data_) |
| 497 data_->header.crash = 0; | 505 data_->header.crash = 0; |
| 498 | 506 |
| 499 File::WaitForPendingIO(&num_pending_io_); | |
| 500 if (user_flags_ & kNoRandom) { | 507 if (user_flags_ & kNoRandom) { |
| 501 // This is a net_unittest, verify that we are not 'leaking' entries. | 508 // This is a net_unittest, verify that we are not 'leaking' entries. |
| 509 File::WaitForPendingIO(&num_pending_io_); |
| 502 DCHECK(!num_refs_); | 510 DCHECK(!num_refs_); |
| 503 } | 511 } |
| 504 } | 512 } |
| 505 block_files_.CloseFiles(); | 513 block_files_.CloseFiles(); |
| 506 index_ = NULL; | 514 index_ = NULL; |
| 507 ptr_factory_.InvalidateWeakPtrs(); | 515 ptr_factory_.InvalidateWeakPtrs(); |
| 508 done_.Signal(); | 516 done_.Signal(); |
| 509 } | 517 } |
| 510 | 518 |
| 511 // ------------------------------------------------------------------------ | 519 // ------------------------------------------------------------------------ |
| 512 | 520 |
| 513 int BackendImpl::OpenPrevEntry(void** iter, Entry** prev_entry, | 521 int BackendImpl::OpenPrevEntry(void** iter, Entry** prev_entry, |
| 514 const net::CompletionCallback& callback) { | 522 const CompletionCallback& callback) { |
| 515 DCHECK(!callback.is_null()); | 523 DCHECK(!callback.is_null()); |
| 516 background_queue_.OpenPrevEntry(iter, prev_entry, callback); | 524 background_queue_.OpenPrevEntry(iter, prev_entry, callback); |
| 517 return net::ERR_IO_PENDING; | 525 return net::ERR_IO_PENDING; |
| 518 } | 526 } |
| 519 | 527 |
| 520 int BackendImpl::SyncOpenEntry(const std::string& key, Entry** entry) { | 528 int BackendImpl::SyncOpenEntry(const std::string& key, Entry** entry) { |
| 521 DCHECK(entry); | 529 DCHECK(entry); |
| 522 *entry = OpenEntryImpl(key); | 530 *entry = OpenEntryImpl(key); |
| 523 return (*entry) ? net::OK : net::ERR_FAILED; | 531 return (*entry) ? net::OK : net::ERR_FAILED; |
| 524 } | 532 } |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 std::string tmp = base::StringPrintf("f_%06x", address.FileNumber()); | 827 std::string tmp = base::StringPrintf("f_%06x", address.FileNumber()); |
| 820 return path_.AppendASCII(tmp); | 828 return path_.AppendASCII(tmp); |
| 821 } | 829 } |
| 822 | 830 |
| 823 MappedFile* BackendImpl::File(Addr address) { | 831 MappedFile* BackendImpl::File(Addr address) { |
| 824 if (disabled_) | 832 if (disabled_) |
| 825 return NULL; | 833 return NULL; |
| 826 return block_files_.GetFile(address); | 834 return block_files_.GetFile(address); |
| 827 } | 835 } |
| 828 | 836 |
| 837 base::WeakPtr<InFlightBackendIO> BackendImpl::GetBackgroundQueue() { |
| 838 return background_queue_.GetWeakPtr(); |
| 839 } |
| 840 |
| 829 bool BackendImpl::CreateExternalFile(Addr* address) { | 841 bool BackendImpl::CreateExternalFile(Addr* address) { |
| 830 int file_number = data_->header.last_file + 1; | 842 int file_number = data_->header.last_file + 1; |
| 831 Addr file_address(0); | 843 Addr file_address(0); |
| 832 bool success = false; | 844 bool success = false; |
| 833 for (int i = 0; i < 0x0fffffff; i++, file_number++) { | 845 for (int i = 0; i < 0x0fffffff; i++, file_number++) { |
| 834 if (!file_address.SetFileNumber(file_number)) { | 846 if (!file_address.SetFileNumber(file_number)) { |
| 835 file_number = 1; | 847 file_number = 1; |
| 836 continue; | 848 continue; |
| 837 } | 849 } |
| 838 FilePath name = GetFileName(file_address); | 850 FilePath name = GetFileName(file_address); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 | 989 |
| 978 void BackendImpl::OnEntryDestroyBegin(Addr address) { | 990 void BackendImpl::OnEntryDestroyBegin(Addr address) { |
| 979 EntriesMap::iterator it = open_entries_.find(address.value()); | 991 EntriesMap::iterator it = open_entries_.find(address.value()); |
| 980 if (it != open_entries_.end()) | 992 if (it != open_entries_.end()) |
| 981 open_entries_.erase(it); | 993 open_entries_.erase(it); |
| 982 } | 994 } |
| 983 | 995 |
| 984 void BackendImpl::OnEntryDestroyEnd() { | 996 void BackendImpl::OnEntryDestroyEnd() { |
| 985 DecreaseNumRefs(); | 997 DecreaseNumRefs(); |
| 986 if (data_->header.num_bytes > max_size_ && !read_only_ && | 998 if (data_->header.num_bytes > max_size_ && !read_only_ && |
| 987 (up_ticks_ > kTrimDelay || user_flags_ & disk_cache::kNoRandom)) | 999 (up_ticks_ > kTrimDelay || user_flags_ & kNoRandom)) |
| 988 eviction_.TrimCache(false); | 1000 eviction_.TrimCache(false); |
| 989 } | 1001 } |
| 990 | 1002 |
| 991 EntryImpl* BackendImpl::GetOpenEntry(CacheRankingsBlock* rankings) const { | 1003 EntryImpl* BackendImpl::GetOpenEntry(CacheRankingsBlock* rankings) const { |
| 992 DCHECK(rankings->HasData()); | 1004 DCHECK(rankings->HasData()); |
| 993 EntriesMap::const_iterator it = | 1005 EntriesMap::const_iterator it = |
| 994 open_entries_.find(rankings->Data()->contents); | 1006 open_entries_.find(rankings->Data()->contents); |
| 995 if (it != open_entries_.end()) { | 1007 if (it != open_entries_.end()) { |
| 996 // We have this entry in memory. | 1008 // We have this entry in memory. |
| 997 return it->second; | 1009 return it->second; |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 } | 1249 } |
| 1238 | 1250 |
| 1239 void BackendImpl::SetFlags(uint32 flags) { | 1251 void BackendImpl::SetFlags(uint32 flags) { |
| 1240 user_flags_ |= flags; | 1252 user_flags_ |= flags; |
| 1241 } | 1253 } |
| 1242 | 1254 |
| 1243 void BackendImpl::ClearRefCountForTest() { | 1255 void BackendImpl::ClearRefCountForTest() { |
| 1244 num_refs_ = 0; | 1256 num_refs_ = 0; |
| 1245 } | 1257 } |
| 1246 | 1258 |
| 1247 int BackendImpl::FlushQueueForTest(const net::CompletionCallback& callback) { | 1259 int BackendImpl::FlushQueueForTest(const CompletionCallback& callback) { |
| 1248 background_queue_.FlushQueue(callback); | 1260 background_queue_.FlushQueue(callback); |
| 1249 return net::ERR_IO_PENDING; | 1261 return net::ERR_IO_PENDING; |
| 1250 } | 1262 } |
| 1251 | 1263 |
| 1252 int BackendImpl::RunTaskForTest(const base::Closure& task, | 1264 int BackendImpl::RunTaskForTest(const base::Closure& task, |
| 1253 const net::CompletionCallback& callback) { | 1265 const CompletionCallback& callback) { |
| 1254 background_queue_.RunTask(task, callback); | 1266 background_queue_.RunTask(task, callback); |
| 1255 return net::ERR_IO_PENDING; | 1267 return net::ERR_IO_PENDING; |
| 1256 } | 1268 } |
| 1257 | 1269 |
| 1258 void BackendImpl::TrimForTest(bool empty) { | 1270 void BackendImpl::TrimForTest(bool empty) { |
| 1259 eviction_.SetTestMode(); | 1271 eviction_.SetTestMode(); |
| 1260 eviction_.TrimCache(empty); | 1272 eviction_.TrimCache(empty); |
| 1261 } | 1273 } |
| 1262 | 1274 |
| 1263 void BackendImpl::TrimDeletedListForTest(bool empty) { | 1275 void BackendImpl::TrimDeletedListForTest(bool empty) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 | 1312 |
| 1301 if (not_deleted < 0) { | 1313 if (not_deleted < 0) { |
| 1302 NOTREACHED(); | 1314 NOTREACHED(); |
| 1303 not_deleted = 0; | 1315 not_deleted = 0; |
| 1304 } | 1316 } |
| 1305 | 1317 |
| 1306 return not_deleted; | 1318 return not_deleted; |
| 1307 } | 1319 } |
| 1308 | 1320 |
| 1309 int BackendImpl::OpenEntry(const std::string& key, Entry** entry, | 1321 int BackendImpl::OpenEntry(const std::string& key, Entry** entry, |
| 1310 const net::CompletionCallback& callback) { | 1322 const CompletionCallback& callback) { |
| 1311 DCHECK(!callback.is_null()); | 1323 DCHECK(!callback.is_null()); |
| 1312 background_queue_.OpenEntry(key, entry, callback); | 1324 background_queue_.OpenEntry(key, entry, callback); |
| 1313 return net::ERR_IO_PENDING; | 1325 return net::ERR_IO_PENDING; |
| 1314 } | 1326 } |
| 1315 | 1327 |
| 1316 int BackendImpl::CreateEntry(const std::string& key, Entry** entry, | 1328 int BackendImpl::CreateEntry(const std::string& key, Entry** entry, |
| 1317 const net::CompletionCallback& callback) { | 1329 const CompletionCallback& callback) { |
| 1318 DCHECK(!callback.is_null()); | 1330 DCHECK(!callback.is_null()); |
| 1319 background_queue_.CreateEntry(key, entry, callback); | 1331 background_queue_.CreateEntry(key, entry, callback); |
| 1320 return net::ERR_IO_PENDING; | 1332 return net::ERR_IO_PENDING; |
| 1321 } | 1333 } |
| 1322 | 1334 |
| 1323 int BackendImpl::DoomEntry(const std::string& key, | 1335 int BackendImpl::DoomEntry(const std::string& key, |
| 1324 const net::CompletionCallback& callback) { | 1336 const CompletionCallback& callback) { |
| 1325 DCHECK(!callback.is_null()); | 1337 DCHECK(!callback.is_null()); |
| 1326 background_queue_.DoomEntry(key, callback); | 1338 background_queue_.DoomEntry(key, callback); |
| 1327 return net::ERR_IO_PENDING; | 1339 return net::ERR_IO_PENDING; |
| 1328 } | 1340 } |
| 1329 | 1341 |
| 1330 int BackendImpl::DoomAllEntries(const net::CompletionCallback& callback) { | 1342 int BackendImpl::DoomAllEntries(const CompletionCallback& callback) { |
| 1331 DCHECK(!callback.is_null()); | 1343 DCHECK(!callback.is_null()); |
| 1332 background_queue_.DoomAllEntries(callback); | 1344 background_queue_.DoomAllEntries(callback); |
| 1333 return net::ERR_IO_PENDING; | 1345 return net::ERR_IO_PENDING; |
| 1334 } | 1346 } |
| 1335 | 1347 |
| 1336 int BackendImpl::DoomEntriesBetween(const base::Time initial_time, | 1348 int BackendImpl::DoomEntriesBetween(const base::Time initial_time, |
| 1337 const base::Time end_time, | 1349 const base::Time end_time, |
| 1338 const net::CompletionCallback& callback) { | 1350 const CompletionCallback& callback) { |
| 1339 DCHECK(!callback.is_null()); | 1351 DCHECK(!callback.is_null()); |
| 1340 background_queue_.DoomEntriesBetween(initial_time, end_time, callback); | 1352 background_queue_.DoomEntriesBetween(initial_time, end_time, callback); |
| 1341 return net::ERR_IO_PENDING; | 1353 return net::ERR_IO_PENDING; |
| 1342 } | 1354 } |
| 1343 | 1355 |
| 1344 int BackendImpl::DoomEntriesSince(const base::Time initial_time, | 1356 int BackendImpl::DoomEntriesSince(const base::Time initial_time, |
| 1345 const net::CompletionCallback& callback) { | 1357 const CompletionCallback& callback) { |
| 1346 DCHECK(!callback.is_null()); | 1358 DCHECK(!callback.is_null()); |
| 1347 background_queue_.DoomEntriesSince(initial_time, callback); | 1359 background_queue_.DoomEntriesSince(initial_time, callback); |
| 1348 return net::ERR_IO_PENDING; | 1360 return net::ERR_IO_PENDING; |
| 1349 } | 1361 } |
| 1350 | 1362 |
| 1351 int BackendImpl::OpenNextEntry(void** iter, Entry** next_entry, | 1363 int BackendImpl::OpenNextEntry(void** iter, Entry** next_entry, |
| 1352 const net::CompletionCallback& callback) { | 1364 const CompletionCallback& callback) { |
| 1353 DCHECK(!callback.is_null()); | 1365 DCHECK(!callback.is_null()); |
| 1354 background_queue_.OpenNextEntry(iter, next_entry, callback); | 1366 background_queue_.OpenNextEntry(iter, next_entry, callback); |
| 1355 return net::ERR_IO_PENDING; | 1367 return net::ERR_IO_PENDING; |
| 1356 } | 1368 } |
| 1357 | 1369 |
| 1358 void BackendImpl::EndEnumeration(void** iter) { | 1370 void BackendImpl::EndEnumeration(void** iter) { |
| 1359 background_queue_.EndEnumeration(*iter); | 1371 background_queue_.EndEnumeration(*iter); |
| 1360 *iter = NULL; | 1372 *iter = NULL; |
| 1361 } | 1373 } |
| 1362 | 1374 |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2166 if (total_memory > kMaxBuffersSize || total_memory <= 0) | 2178 if (total_memory > kMaxBuffersSize || total_memory <= 0) |
| 2167 total_memory = kMaxBuffersSize; | 2179 total_memory = kMaxBuffersSize; |
| 2168 | 2180 |
| 2169 done = true; | 2181 done = true; |
| 2170 } | 2182 } |
| 2171 | 2183 |
| 2172 return static_cast<int>(total_memory); | 2184 return static_cast<int>(total_memory); |
| 2173 } | 2185 } |
| 2174 | 2186 |
| 2175 } // namespace disk_cache | 2187 } // namespace disk_cache |
| OLD | NEW |