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 |