Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: content/browser/dom_storage/dom_storage_context_impl.cc

Issue 1953703004: Purge browser cache for dom storage in a smarter way (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dom_storage
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "content/browser/dom_storage/dom_storage_context_impl.h" 5 #include "content/browser/dom_storage/dom_storage_context_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 17 matching lines...) Expand all
28 #include "storage/browser/quota/special_storage_policy.h" 28 #include "storage/browser/quota/special_storage_policy.h"
29 29
30 namespace content { 30 namespace content {
31 31
32 static const int kSessionStoraceScavengingSeconds = 60; 32 static const int kSessionStoraceScavengingSeconds = 60;
33 33
34 // Offset the session storage namespace ids generated by different contexts 34 // Offset the session storage namespace ids generated by different contexts
35 // to help identify when an id from one is mistakenly used in another. 35 // to help identify when an id from one is mistakenly used in another.
36 static int g_session_id_offset_sequence = 1; 36 static int g_session_id_offset_sequence = 1;
37 37
38 // Helper class that posts the memory pressure notification on dom storage task
39 // runner.
40 class DOMStorageContextImpl::DOMStorageMemoryPressureListener {
41 public:
42 DOMStorageMemoryPressureListener(DOMStorageTaskRunner* task_runner,
43 DOMStorageContextImpl* context)
44 : task_runner_(task_runner),
45 context_(context),
46 listener_(
47 base::Bind(&DOMStorageMemoryPressureListener::OnMemoryPressure,
48 base::Unretained(this))) {}
49
50 void OnMemoryPressure(
51 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
52 base::AutoLock lock(lock_);
53 if (task_runner_) {
54 task_runner_->PostTask(
55 FROM_HERE, base::Bind(&DOMStorageContextImpl::PurgeMemory, context_,
56 memory_pressure_level));
57 }
58 }
59
60 void Shutdown() {
61 base::AutoLock lock(lock_);
michaeln 2016/05/09 21:50:31 Lets avoid leaks and locks for this. Having a sepa
ssid 2016/05/10 02:04:16 listener in DOMStorageContextWrapper sounds like a
62 task_runner_ = nullptr;
63 context_ = nullptr;
64 }
65
66 private:
67 scoped_refptr<DOMStorageTaskRunner> task_runner_;
68 scoped_refptr<DOMStorageContextImpl> context_;
69 base::MemoryPressureListener listener_;
70 base::Lock lock_;
71 };
72
38 DOMStorageContextImpl::DOMStorageContextImpl( 73 DOMStorageContextImpl::DOMStorageContextImpl(
39 const base::FilePath& localstorage_directory, 74 const base::FilePath& localstorage_directory,
40 const base::FilePath& sessionstorage_directory, 75 const base::FilePath& sessionstorage_directory,
41 storage::SpecialStoragePolicy* special_storage_policy, 76 storage::SpecialStoragePolicy* special_storage_policy,
42 DOMStorageTaskRunner* task_runner) 77 DOMStorageTaskRunner* task_runner)
43 : localstorage_directory_(localstorage_directory), 78 : localstorage_directory_(localstorage_directory),
44 sessionstorage_directory_(sessionstorage_directory), 79 sessionstorage_directory_(sessionstorage_directory),
45 task_runner_(task_runner), 80 task_runner_(task_runner),
46 session_id_offset_(abs((g_session_id_offset_sequence++ % 10)) * 1000), 81 session_id_offset_(abs((g_session_id_offset_sequence++ % 10)) * 1000),
47 is_shutdown_(false), 82 is_shutdown_(false),
48 force_keep_session_state_(false), 83 force_keep_session_state_(false),
49 special_storage_policy_(special_storage_policy), 84 special_storage_policy_(special_storage_policy),
50 scavenging_started_(false) { 85 scavenging_started_(false) {
51 // AtomicSequenceNum starts at 0 but we want to start session 86 // AtomicSequenceNum starts at 0 but we want to start session
52 // namespace ids at one since zero is reserved for the 87 // namespace ids at one since zero is reserved for the
53 // kLocalStorageNamespaceId. 88 // kLocalStorageNamespaceId.
54 session_id_sequence_.GetNext(); 89 session_id_sequence_.GetNext();
55 90
56 // Tests may run without task runners. 91 // Tests may run without task runners.
57 if (task_runner_) { 92 if (task_runner_) {
93 // Created for each DOMStorageContextImpl object and is leaked since
94 // destruction is not thread safe.
95 leaked_memory_pressure_listener_ =
96 new DOMStorageMemoryPressureListener(task_runner, this);
97
58 // Registering dump provider is safe even outside the task runner. 98 // Registering dump provider is safe even outside the task runner.
59 base::trace_event::MemoryDumpManager::GetInstance() 99 base::trace_event::MemoryDumpManager::GetInstance()
60 ->RegisterDumpProviderWithSequencedTaskRunner( 100 ->RegisterDumpProviderWithSequencedTaskRunner(
61 this, "DOMStorage", task_runner_->GetSequencedTaskRunner( 101 this, "DOMStorage", task_runner_->GetSequencedTaskRunner(
62 DOMStorageTaskRunner::PRIMARY_SEQUENCE), 102 DOMStorageTaskRunner::PRIMARY_SEQUENCE),
63 base::trace_event::MemoryDumpProvider::Options()); 103 base::trace_event::MemoryDumpProvider::Options());
64 } 104 }
65 } 105 }
66 106
67 DOMStorageContextImpl::~DOMStorageContextImpl() { 107 DOMStorageContextImpl::~DOMStorageContextImpl() {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 entry.second->Flush(); 226 entry.second->Flush();
187 } 227 }
188 228
189 void DOMStorageContextImpl::Shutdown() { 229 void DOMStorageContextImpl::Shutdown() {
190 DCHECK(!task_runner_ || task_runner_->IsRunningOnPrimarySequence()); 230 DCHECK(!task_runner_ || task_runner_->IsRunningOnPrimarySequence());
191 is_shutdown_ = true; 231 is_shutdown_ = true;
192 StorageNamespaceMap::const_iterator it = namespaces_.begin(); 232 StorageNamespaceMap::const_iterator it = namespaces_.begin();
193 for (; it != namespaces_.end(); ++it) 233 for (; it != namespaces_.end(); ++it)
194 it->second->Shutdown(); 234 it->second->Shutdown();
195 235
236 leaked_memory_pressure_listener_->Shutdown();
237
196 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 238 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
197 this); 239 this);
198 240
199 if (localstorage_directory_.empty() && !session_storage_database_.get()) 241 if (localstorage_directory_.empty() && !session_storage_database_.get())
200 return; 242 return;
201 243
202 // Respect the content policy settings about what to 244 // Respect the content policy settings about what to
203 // keep and what to discard. 245 // keep and what to discard.
204 if (force_keep_session_state_) 246 if (force_keep_session_state_)
205 return; // Keep everything. 247 return; // Keep everything.
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 409
368 void DOMStorageContextImpl::StartScavengingUnusedSessionStorage() { 410 void DOMStorageContextImpl::StartScavengingUnusedSessionStorage() {
369 if (session_storage_database_.get()) { 411 if (session_storage_database_.get()) {
370 task_runner_->PostDelayedTask( 412 task_runner_->PostDelayedTask(
371 FROM_HERE, base::Bind(&DOMStorageContextImpl::FindUnusedNamespaces, 413 FROM_HERE, base::Bind(&DOMStorageContextImpl::FindUnusedNamespaces,
372 this), 414 this),
373 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); 415 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds));
374 } 416 }
375 } 417 }
376 418
419 void DOMStorageContextImpl::PurgeMemory(
420 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
421 if (is_shutdown_)
422 return;
423
424 DOMStorageNamespace::PurgeOption option = DOMStorageNamespace::PURGE_UNOPENED;
425 if (memory_pressure_level ==
426 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
427 option = DOMStorageNamespace::PURGE_AGGRESSIVE;
428 for (const auto& it : namespaces_)
429 it.second->PurgeMemory(option);
430 }
431
377 bool DOMStorageContextImpl::OnMemoryDump( 432 bool DOMStorageContextImpl::OnMemoryDump(
378 const base::trace_event::MemoryDumpArgs& args, 433 const base::trace_event::MemoryDumpArgs& args,
379 base::trace_event::ProcessMemoryDump* pmd) { 434 base::trace_event::ProcessMemoryDump* pmd) {
380 for (const auto& it : namespaces_) { 435 for (const auto& it : namespaces_) {
381 it.second->OnMemoryDump(pmd); 436 it.second->OnMemoryDump(pmd);
382 } 437 }
383 if (session_storage_database_) 438 if (session_storage_database_)
384 session_storage_database_->OnMemoryDump(pmd); 439 session_storage_database_->OnMemoryDump(pmd);
385 return true; 440 return true;
386 } 441 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 if (!deletable_persistent_namespace_ids_.empty()) { 503 if (!deletable_persistent_namespace_ids_.empty()) {
449 task_runner_->PostDelayedTask( 504 task_runner_->PostDelayedTask(
450 FROM_HERE, base::Bind( 505 FROM_HERE, base::Bind(
451 &DOMStorageContextImpl::DeleteNextUnusedNamespace, 506 &DOMStorageContextImpl::DeleteNextUnusedNamespace,
452 this), 507 this),
453 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); 508 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds));
454 } 509 }
455 } 510 }
456 511
457 } // namespace content 512 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698