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

Side by Side Diff: chrome/browser/in_process_webkit/dom_storage_context.cc

Issue 545054: Introduce all the plumbing for Session Storage. This mostly consists of crea... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "chrome/browser/in_process_webkit/dom_storage_context.h" 5 #include "chrome/browser/in_process_webkit/dom_storage_context.h"
6 6
7 #include "base/file_path.h" 7 #include "base/file_path.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "chrome/browser/chrome_thread.h" 9 #include "chrome/browser/chrome_thread.h"
10 #include "chrome/browser/in_process_webkit/dom_storage_area.h" 10 #include "chrome/browser/in_process_webkit/dom_storage_area.h"
11 #include "chrome/browser/in_process_webkit/dom_storage_namespace.h" 11 #include "chrome/browser/in_process_webkit/dom_storage_namespace.h"
12 #include "chrome/browser/in_process_webkit/webkit_context.h" 12 #include "chrome/browser/in_process_webkit/webkit_context.h"
13 #include "chrome/common/dom_storage_common.h"
13 14
14 static const char* kLocalStorageDirectory = "Local Storage"; 15 static const char* kLocalStorageDirectory = "Local Storage";
15 16
16 // TODO(jorlow): Remove after Chrome 4 ships. 17 // TODO(jorlow): Remove after Chrome 4 ships.
17 static void MigrateLocalStorageDirectory(const FilePath& data_path) { 18 static void MigrateLocalStorageDirectory(const FilePath& data_path) {
18 FilePath new_path = data_path.AppendASCII(kLocalStorageDirectory); 19 FilePath new_path = data_path.AppendASCII(kLocalStorageDirectory);
19 FilePath old_path = data_path.AppendASCII("localStorage"); 20 FilePath old_path = data_path.AppendASCII("localStorage");
20 if (!file_util::DirectoryExists(new_path) && 21 if (!file_util::DirectoryExists(new_path) &&
21 file_util::DirectoryExists(old_path)) { 22 file_util::DirectoryExists(old_path)) {
22 file_util::Move(old_path, new_path); 23 file_util::Move(old_path, new_path);
23 } 24 }
24 } 25 }
25 26
26 DOMStorageContext::DOMStorageContext(WebKitContext* webkit_context) 27 DOMStorageContext::DOMStorageContext(WebKitContext* webkit_context)
27 : last_storage_area_id_(kFirstStorageAreaId), 28 : last_storage_area_id_(0),
28 last_storage_namespace_id_(kFirstStorageNamespaceId), 29 last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId),
30 last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId),
29 webkit_context_(webkit_context) { 31 webkit_context_(webkit_context) {
30 } 32 }
31 33
32 DOMStorageContext::~DOMStorageContext() { 34 DOMStorageContext::~DOMStorageContext() {
33 // This should not go away until all DOM Storage Dispatcher hosts have gone 35 // This should not go away until all DOM Storage Dispatcher hosts have gone
34 // away. And they remove themselves from this list. 36 // away. And they remove themselves from this list.
35 DCHECK(dispatcher_host_set_.empty()); 37 DCHECK(dispatcher_host_set_.empty());
36 38
37 // If we don't have any work to do on the WebKit thread, bail. 39 for (StorageNamespaceMap::iterator iter(storage_namespace_map_.begin());
38 if (storage_namespace_map_.empty()) 40 iter != storage_namespace_map_.end(); ++iter) {
39 return; 41 delete iter->second;
40 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); 42 }
41
42 // The storage namespace destructor unregisters the storage namespace, so
43 // our iterator becomes invalid. Thus we just keep deleting the first item
44 // until there are none left.
45 while (!storage_namespace_map_.empty())
46 delete storage_namespace_map_.begin()->second;
47 } 43 }
48 44
49 DOMStorageNamespace* DOMStorageContext::LocalStorage() { 45 int64 DOMStorageContext::AllocateStorageAreaId() {
50 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); 46 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
51 DOMStorageNamespace* storage_namespace = GetStorageNamespace( 47 return ++last_storage_area_id_;
52 kLocalStorageNamespaceId);
53 if (storage_namespace)
54 return storage_namespace;
55
56 FilePath data_path = webkit_context_->data_path();
57 FilePath dir_path;
58 if (!data_path.empty()) {
59 MigrateLocalStorageDirectory(data_path);
60 dir_path = data_path.AppendASCII(kLocalStorageDirectory);
61 }
62 return DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path);
63 } 48 }
64 49
65 DOMStorageNamespace* DOMStorageContext::NewSessionStorage() { 50 int64 DOMStorageContext::AllocateSessionStorageNamespaceId() {
66 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); 51 if (ChromeThread::CurrentlyOn(ChromeThread::UI))
67 return DOMStorageNamespace::CreateSessionStorageNamespace(this); 52 return ++last_session_storage_namespace_id_on_ui_thread_;
53 return --last_session_storage_namespace_id_on_io_thread_;
54 }
55
56 int64 DOMStorageContext::CloneSessionStorage(int64 original_id) {
57 DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
58 int64 clone_id = AllocateSessionStorageNamespaceId();
59 ChromeThread::PostTask(
60 ChromeThread::WEBKIT, FROM_HERE, NewRunnableFunction(
61 &DOMStorageContext::CompleteCloningSessionStorage,
62 this, original_id, clone_id));
63 return clone_id;
68 } 64 }
69 65
70 void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) { 66 void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) {
71 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); 67 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
72 int64 id = storage_area->id(); 68 int64 id = storage_area->id();
73 DCHECK(!GetStorageArea(id)); 69 DCHECK(!GetStorageArea(id));
74 storage_area_map_[id] = storage_area; 70 storage_area_map_[id] = storage_area;
75 } 71 }
76 72
77 void DOMStorageContext::UnregisterStorageArea(DOMStorageArea* storage_area) { 73 void DOMStorageContext::UnregisterStorageArea(DOMStorageArea* storage_area) {
78 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); 74 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
79 int64 id = storage_area->id(); 75 int64 id = storage_area->id();
80 DCHECK(GetStorageArea(id)); 76 DCHECK(GetStorageArea(id));
81 storage_area_map_.erase(id); 77 storage_area_map_.erase(id);
82 } 78 }
83 79
84 DOMStorageArea* DOMStorageContext::GetStorageArea(int64 id) { 80 DOMStorageArea* DOMStorageContext::GetStorageArea(int64 id) {
85 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); 81 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
86 StorageAreaMap::iterator iter = storage_area_map_.find(id); 82 StorageAreaMap::iterator iter = storage_area_map_.find(id);
87 if (iter == storage_area_map_.end()) 83 if (iter == storage_area_map_.end())
88 return NULL; 84 return NULL;
89 return iter->second; 85 return iter->second;
90 } 86 }
91 87
92 void DOMStorageContext::RegisterStorageNamespace( 88 void DOMStorageContext::DeleteSessionStorageNamespace(int64 namespace_id) {
93 DOMStorageNamespace* storage_namespace) {
94 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); 89 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
95 int64 id = storage_namespace->id(); 90 StorageNamespaceMap::iterator iter =
96 DCHECK(!GetStorageNamespace(id)); 91 storage_namespace_map_.find(namespace_id);
97 storage_namespace_map_[id] = storage_namespace; 92 if (iter == storage_namespace_map_.end())
93 return;
94 DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION);
95 delete iter->second;
96 storage_namespace_map_.erase(iter);
98 } 97 }
99 98
100 void DOMStorageContext::UnregisterStorageNamespace( 99 DOMStorageNamespace* DOMStorageContext::GetStorageNamespace(
101 DOMStorageNamespace* storage_namespace) { 100 int64 id, bool allocation_allowed) {
102 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
103 int64 id = storage_namespace->id();
104 DCHECK(GetStorageNamespace(id));
105 storage_namespace_map_.erase(id);
106 }
107
108 DOMStorageNamespace* DOMStorageContext::GetStorageNamespace(int64 id) {
109 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); 101 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
110 StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id); 102 StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id);
111 if (iter == storage_namespace_map_.end()) 103 if (iter != storage_namespace_map_.end())
104 return iter->second;
105 if (!allocation_allowed)
112 return NULL; 106 return NULL;
113 return iter->second; 107 if (id == kLocalStorageNamespaceId)
108 return CreateLocalStorage();
109 return CreateSessionStorage(id);
114 } 110 }
115 111
116 void DOMStorageContext::RegisterDispatcherHost( 112 void DOMStorageContext::RegisterDispatcherHost(
117 DOMStorageDispatcherHost* dispatcher_host) { 113 DOMStorageDispatcherHost* dispatcher_host) {
118 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 114 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
119 DCHECK(dispatcher_host_set_.find(dispatcher_host) == 115 DCHECK(dispatcher_host_set_.find(dispatcher_host) ==
120 dispatcher_host_set_.end()); 116 dispatcher_host_set_.end());
121 dispatcher_host_set_.insert(dispatcher_host); 117 dispatcher_host_set_.insert(dispatcher_host);
122 } 118 }
123 119
(...skipping 10 matching lines...) Expand all
134 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 130 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
135 return &dispatcher_host_set_; 131 return &dispatcher_host_set_;
136 } 132 }
137 133
138 void DOMStorageContext::PurgeMemory() { 134 void DOMStorageContext::PurgeMemory() {
139 // It is only safe to purge the memory from the LocalStorage namespace, 135 // It is only safe to purge the memory from the LocalStorage namespace,
140 // because it is backed by disk and can be reloaded later. If we purge a 136 // because it is backed by disk and can be reloaded later. If we purge a
141 // SessionStorage namespace, its data will be gone forever, because it isn't 137 // SessionStorage namespace, its data will be gone forever, because it isn't
142 // currently backed by disk. 138 // currently backed by disk.
143 DOMStorageNamespace* local_storage = 139 DOMStorageNamespace* local_storage =
144 GetStorageNamespace(kLocalStorageNamespaceId); 140 GetStorageNamespace(kLocalStorageNamespaceId, false);
145 if (local_storage) 141 if (local_storage)
146 local_storage->PurgeMemory(); 142 local_storage->PurgeMemory();
147 } 143 }
148 144
149 void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) { 145 void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) {
150 // Make sure that we don't delete a database that's currently being accessed 146 // Make sure that we don't delete a database that's currently being accessed
151 // by unloading all of the databases temporarily. 147 // by unloading all of the databases temporarily.
152 PurgeMemory(); 148 PurgeMemory();
153 149
154 file_util::FileEnumerator file_enumerator( 150 file_util::FileEnumerator file_enumerator(
155 webkit_context_->data_path().AppendASCII(kLocalStorageDirectory), false, 151 webkit_context_->data_path().AppendASCII(kLocalStorageDirectory), false,
156 file_util::FileEnumerator::FILES); 152 file_util::FileEnumerator::FILES);
157 for (FilePath path = file_enumerator.Next(); !path.value().empty(); 153 for (FilePath path = file_enumerator.Next(); !path.value().empty();
158 path = file_enumerator.Next()) { 154 path = file_enumerator.Next()) {
159 file_util::FileEnumerator::FindInfo find_info; 155 file_util::FileEnumerator::FindInfo find_info;
160 file_enumerator.GetFindInfo(&find_info); 156 file_enumerator.GetFindInfo(&find_info);
161 if (file_util::HasFileBeenModifiedSince(find_info, cutoff)) 157 if (file_util::HasFileBeenModifiedSince(find_info, cutoff))
162 file_util::Delete(path, false); 158 file_util::Delete(path, false);
163 } 159 }
164 } 160 }
161
162 DOMStorageNamespace* DOMStorageContext::CreateLocalStorage() {
163 FilePath data_path = webkit_context_->data_path();
164 FilePath dir_path;
165 if (!data_path.empty()) {
166 MigrateLocalStorageDirectory(data_path);
167 dir_path = data_path.AppendASCII(kLocalStorageDirectory);
168 }
169 DOMStorageNamespace* new_namespace =
170 DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path);
171 RegisterStorageNamespace(new_namespace);
172 return new_namespace;
173 }
174
175 DOMStorageNamespace* DOMStorageContext::CreateSessionStorage(
176 int64 namespace_id) {
177 DOMStorageNamespace* new_namespace =
178 DOMStorageNamespace::CreateSessionStorageNamespace(this, namespace_id);
179 RegisterStorageNamespace(new_namespace);
180 return new_namespace;
181 }
182
183 void DOMStorageContext::RegisterStorageNamespace(
184 DOMStorageNamespace* storage_namespace) {
185 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
186 int64 id = storage_namespace->id();
187 DCHECK(!GetStorageNamespace(id, false));
188 storage_namespace_map_[id] = storage_namespace;
189 }
190
191 /* static */
192 void DOMStorageContext::CompleteCloningSessionStorage(
193 DOMStorageContext* context, int64 existing_id, int64 clone_id) {
194 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT));
195 DOMStorageNamespace* existing_namespace =
196 context->GetStorageNamespace(existing_id, false);
197 // If nothing exists, then there's nothing to clone.
198 if (existing_namespace)
199 context->RegisterStorageNamespace(existing_namespace->Copy(clone_id));
200 }
OLDNEW
« no previous file with comments | « chrome/browser/in_process_webkit/dom_storage_context.h ('k') | chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698