Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/simple/simple_backend_impl.h" | 5 #include "net/disk_cache/simple/simple_backend_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstdlib> | 8 #include <cstdlib> |
| 9 | 9 |
| 10 #if defined(OS_POSIX) | 10 #if defined(OS_POSIX) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 | 52 |
| 53 // Cache size when all other size heuristics failed. | 53 // Cache size when all other size heuristics failed. |
| 54 const uint64 kDefaultCacheSize = 80 * 1024 * 1024; | 54 const uint64 kDefaultCacheSize = 80 * 1024 * 1024; |
| 55 | 55 |
| 56 // Maximum fraction of the cache that one entry can consume. | 56 // Maximum fraction of the cache that one entry can consume. |
| 57 const int kMaxFileRatio = 8; | 57 const int kMaxFileRatio = 8; |
| 58 | 58 |
| 59 // A global sequenced worker pool to use for launching all tasks. | 59 // A global sequenced worker pool to use for launching all tasks. |
| 60 SequencedWorkerPool* g_sequenced_worker_pool = NULL; | 60 SequencedWorkerPool* g_sequenced_worker_pool = NULL; |
| 61 | 61 |
| 62 class DoomEntrySetContext : public base::RefCounted<DoomEntrySetContext> { | |
| 63 public: | |
| 64 DoomEntrySetContext() : entries_left(0), error_happened(false) {} | |
| 65 | |
| 66 int entries_left; // Number of entries that remain to be doomed. | |
| 67 bool error_happened; | |
| 68 | |
| 69 private: | |
| 70 friend class base::RefCounted<DoomEntrySetContext>; | |
| 71 | |
| 72 ~DoomEntrySetContext() {} | |
| 73 }; | |
| 74 | |
| 62 void MaybeCreateSequencedWorkerPool() { | 75 void MaybeCreateSequencedWorkerPool() { |
| 63 if (!g_sequenced_worker_pool) { | 76 if (!g_sequenced_worker_pool) { |
| 64 int max_worker_threads = kDefaultMaxWorkerThreads; | 77 int max_worker_threads = kDefaultMaxWorkerThreads; |
| 65 | 78 |
| 66 const std::string thread_count_field_trial = | 79 const std::string thread_count_field_trial = |
| 67 base::FieldTrialList::FindFullName("SimpleCacheMaxThreads"); | 80 base::FieldTrialList::FindFullName("SimpleCacheMaxThreads"); |
| 68 if (!thread_count_field_trial.empty()) { | 81 if (!thread_count_field_trial.empty()) { |
| 69 max_worker_threads = | 82 max_worker_threads = |
| 70 std::max(1, std::atoi(thread_count_field_trial.c_str())); | 83 std::max(1, std::atoi(thread_count_field_trial.c_str())); |
| 71 } | 84 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 | 211 |
| 199 void RecordIndexLoad(base::TimeTicks constructed_since, int result) { | 212 void RecordIndexLoad(base::TimeTicks constructed_since, int result) { |
| 200 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - | 213 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - |
| 201 constructed_since; | 214 constructed_since; |
| 202 if (result == net::OK) | 215 if (result == net::OK) |
| 203 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndex", creation_to_index); | 216 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndex", creation_to_index); |
| 204 else | 217 else |
| 205 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndexFail", creation_to_index); | 218 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndexFail", creation_to_index); |
| 206 } | 219 } |
| 207 | 220 |
| 221 // Used only by mass dooming to execute the client-provided callback once all | |
| 222 // the entries are doomed. Note that this is called multiple times during a mass | |
| 223 // doom operation (until the number of left entries in the context reaches 0). | |
| 224 void OnDoomEntriesCompleted( | |
| 225 DoomEntrySetContext* context, | |
| 226 const net::CompletionCallback& all_entries_doomed_callback, | |
| 227 int doomed_entries_count, | |
| 228 int net_error) { | |
| 229 context->entries_left -= doomed_entries_count; | |
| 230 if (net_error == net::ERR_FAILED) | |
| 231 context->error_happened = true; | |
| 232 if (context->entries_left == 0 && !all_entries_doomed_callback.is_null()) { | |
| 233 all_entries_doomed_callback.Run( | |
| 234 context->error_happened ? net::ERR_FAILED : net::OK); | |
| 235 } | |
| 236 } | |
| 237 | |
| 208 } // namespace | 238 } // namespace |
| 209 | 239 |
| 210 namespace disk_cache { | 240 namespace disk_cache { |
| 211 | 241 |
| 212 SimpleBackendImpl::SimpleBackendImpl(const FilePath& path, | 242 SimpleBackendImpl::SimpleBackendImpl(const FilePath& path, |
| 213 int max_bytes, | 243 int max_bytes, |
| 214 net::CacheType type, | 244 net::CacheType type, |
| 215 base::SingleThreadTaskRunner* cache_thread, | 245 base::SingleThreadTaskRunner* cache_thread, |
| 216 net::NetLog* net_log) | 246 net::NetLog* net_log) |
| 217 : path_(path), | 247 : path_(path), |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 310 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, | 340 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, |
| 311 Time end_time, | 341 Time end_time, |
| 312 const CompletionCallback& callback, | 342 const CompletionCallback& callback, |
| 313 int result) { | 343 int result) { |
| 314 if (result != net::OK) { | 344 if (result != net::OK) { |
| 315 callback.Run(result); | 345 callback.Run(result); |
| 316 return; | 346 return; |
| 317 } | 347 } |
| 318 scoped_ptr<std::vector<uint64> > removed_key_hashes( | 348 scoped_ptr<std::vector<uint64> > removed_key_hashes( |
| 319 index_->RemoveEntriesBetween(initial_time, end_time).release()); | 349 index_->RemoveEntriesBetween(initial_time, end_time).release()); |
| 320 | 350 const scoped_refptr<DoomEntrySetContext> context(new DoomEntrySetContext()); |
| 351 const CompletionCallback on_entry_doomed_callback = base::Bind( | |
| 352 &OnDoomEntriesCompleted, context, callback, 1 /* entry count */); | |
| 353 int doomed_active_entries_count = 0; | |
| 321 // If any of the entries we are dooming are currently open, we need to remove | 354 // If any of the entries we are dooming are currently open, we need to remove |
| 322 // them from |active_entries_|, so that attempts to create new entries will | 355 // them from |active_entries_|, so that attempts to create new entries will |
| 323 // succeed and attempts to open them will fail. | 356 // succeed and attempts to open them will fail. |
| 324 for (int i = removed_key_hashes->size() - 1; i >= 0; --i) { | 357 for (int i = removed_key_hashes->size() - 1; i >= 0; --i) { |
| 325 const uint64 entry_hash = (*removed_key_hashes)[i]; | 358 const uint64 entry_hash = (*removed_key_hashes)[i]; |
| 326 EntryMap::iterator it = active_entries_.find(entry_hash); | 359 EntryMap::iterator it = active_entries_.find(entry_hash); |
| 327 if (it == active_entries_.end()) | 360 if (it == active_entries_.end()) |
| 328 continue; | 361 continue; |
| 362 ++doomed_active_entries_count; | |
| 329 SimpleEntryImpl* entry = it->second.get(); | 363 SimpleEntryImpl* entry = it->second.get(); |
| 330 entry->Doom(); | 364 entry->DoomEntry(on_entry_doomed_callback); |
| 331 | 365 |
| 332 (*removed_key_hashes)[i] = removed_key_hashes->back(); | 366 (*removed_key_hashes)[i] = removed_key_hashes->back(); |
| 333 removed_key_hashes->resize(removed_key_hashes->size() - 1); | 367 removed_key_hashes->resize(removed_key_hashes->size() - 1); |
| 334 } | 368 } |
| 369 context->entries_left += doomed_active_entries_count; | |
| 370 context->entries_left += removed_key_hashes->size(); | |
| 335 | 371 |
| 336 PostTaskAndReplyWithResult( | 372 PostTaskAndReplyWithResult( |
| 337 worker_pool_, FROM_HERE, | 373 worker_pool_, FROM_HERE, |
| 338 base::Bind(&SimpleSynchronousEntry::DoomEntrySet, | 374 base::Bind(&SimpleSynchronousEntry::DoomEntrySet, |
| 339 base::Passed(&removed_key_hashes), path_), | 375 base::Passed(&removed_key_hashes), path_), |
| 340 base::Bind(&CallCompletionCallback, callback)); | 376 base::Bind(&OnDoomEntriesCompleted, context, callback, |
| 377 removed_key_hashes->size())); | |
|
gavinp
2013/08/27 15:48:02
What was the undefined behaviour?
Deprecated (see juliatuttle)
2013/08/27 16:44:37
+1; this looked fine to me.
Philippe
2013/08/27 16:58:56
Ah thanks Thomas for reminding me this :) So base:
| |
| 341 } | 378 } |
| 342 | 379 |
| 343 int SimpleBackendImpl::DoomEntriesBetween( | 380 int SimpleBackendImpl::DoomEntriesBetween( |
| 344 const Time initial_time, | 381 const Time initial_time, |
| 345 const Time end_time, | 382 const Time end_time, |
| 346 const CompletionCallback& callback) { | 383 const CompletionCallback& callback) { |
| 347 return index_->ExecuteWhenReady( | 384 return index_->ExecuteWhenReady( |
| 348 base::Bind(&SimpleBackendImpl::IndexReadyForDoom, AsWeakPtr(), | 385 base::Bind(&SimpleBackendImpl::IndexReadyForDoom, AsWeakPtr(), |
| 349 initial_time, end_time, callback)); | 386 initial_time, end_time, callback)); |
| 350 } | 387 } |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 561 const CompletionCallback& callback, | 598 const CompletionCallback& callback, |
| 562 int error_code) { | 599 int error_code) { |
| 563 if (error_code == net::ERR_FAILED) { | 600 if (error_code == net::ERR_FAILED) { |
| 564 OpenNextEntry(iter, entry, callback); | 601 OpenNextEntry(iter, entry, callback); |
| 565 return; | 602 return; |
| 566 } | 603 } |
| 567 CallCompletionCallback(callback, error_code); | 604 CallCompletionCallback(callback, error_code); |
| 568 } | 605 } |
| 569 | 606 |
| 570 } // namespace disk_cache | 607 } // namespace disk_cache |
| OLD | NEW |