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 "content/browser/indexed_db/indexed_db_factory.h" | 5 #include "content/browser/indexed_db/indexed_db_factory.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 10 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
52 RemoveDatabaseFromMaps(identifier); | 52 RemoveDatabaseFromMaps(identifier); |
53 | 53 |
54 // No grace period on a forced-close, as the initiator is | 54 // No grace period on a forced-close, as the initiator is |
55 // assuming the backing store will be released once all | 55 // assuming the backing store will be released once all |
56 // connections are closed. | 56 // connections are closed. |
57 ReleaseBackingStore(identifier.first, forcedClose); | 57 ReleaseBackingStore(identifier.first, forcedClose); |
58 } | 58 } |
59 | 59 |
60 void IndexedDBFactory::ReleaseBackingStore(const GURL& origin_url, | 60 void IndexedDBFactory::ReleaseBackingStore(const GURL& origin_url, |
61 bool immediate) { | 61 bool immediate) { |
62 if (immediate) { | |
63 IndexedDBBackingStoreMap::iterator it = | |
64 backing_stores_with_active_blobs_.find(origin_url); | |
65 if (it != backing_stores_with_active_blobs_.end()) { | |
66 it->second->active_blob_registry()->ForceShutdown(); | |
67 backing_stores_with_active_blobs_.erase(it); | |
68 } | |
69 } | |
70 | |
62 // Only close if this is the last reference. | 71 // Only close if this is the last reference. |
63 if (!HasLastBackingStoreReference(origin_url)) | 72 if (!HasLastBackingStoreReference(origin_url)) |
64 return; | 73 return; |
65 | 74 |
66 // If this factory does hold the last reference to the backing store, it can | 75 // If this factory does hold the last reference to the backing store, it can |
67 // be closed - but unless requested to close it immediately, keep it around | 76 // be closed - but unless requested to close it immediately, keep it around |
68 // for a short period so that a re-open is fast. | 77 // for a short period so that a re-open is fast. |
69 if (immediate) { | 78 if (immediate) { |
70 CloseBackingStore(origin_url); | 79 CloseBackingStore(origin_url); |
71 return; | 80 return; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 void IndexedDBFactory::ContextDestroyed() { | 135 void IndexedDBFactory::ContextDestroyed() { |
127 // Timers on backing stores hold a reference to this factory. When the | 136 // Timers on backing stores hold a reference to this factory. When the |
128 // context (which nominally owns this factory) is destroyed during thread | 137 // context (which nominally owns this factory) is destroyed during thread |
129 // termination the timers must be stopped so that this factory and the | 138 // termination the timers must be stopped so that this factory and the |
130 // stores can be disposed of. | 139 // stores can be disposed of. |
131 for (IndexedDBBackingStoreMap::iterator it = backing_store_map_.begin(); | 140 for (IndexedDBBackingStoreMap::iterator it = backing_store_map_.begin(); |
132 it != backing_store_map_.end(); | 141 it != backing_store_map_.end(); |
133 ++it) | 142 ++it) |
134 it->second->close_timer()->Stop(); | 143 it->second->close_timer()->Stop(); |
135 backing_store_map_.clear(); | 144 backing_store_map_.clear(); |
145 backing_stores_with_active_blobs_.clear(); | |
136 context_ = NULL; | 146 context_ = NULL; |
137 } | 147 } |
138 | 148 |
149 void IndexedDBFactory::ReportOutstandingBlobs(const GURL& origin_url, | |
150 bool blobs_outstanding) { | |
151 if (!context_) | |
152 return; | |
153 if (blobs_outstanding) { | |
154 DCHECK(!backing_stores_with_active_blobs_.count(origin_url)); | |
155 IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin_url); | |
156 if (it != backing_store_map_.end()) | |
157 backing_stores_with_active_blobs_.insert(*it); | |
158 else | |
159 DCHECK(false); | |
cmumford
2014/03/24 23:14:35
I'm assuming this is OK for an official build? I c
ericu
2014/03/25 01:22:14
Yeah, it'll compile. It turns into something like
| |
160 } else { | |
161 IndexedDBBackingStoreMap::iterator it = | |
162 backing_stores_with_active_blobs_.find(origin_url); | |
163 if (it != backing_stores_with_active_blobs_.end()) { | |
164 backing_stores_with_active_blobs_.erase(it); | |
165 ReleaseBackingStore(origin_url, false); | |
cmumford
2014/03/24 23:14:35
/*immediate=*/false
ericu
2014/03/25 01:22:14
Done.
| |
166 } | |
167 } | |
168 } | |
169 | |
139 void IndexedDBFactory::GetDatabaseNames( | 170 void IndexedDBFactory::GetDatabaseNames( |
140 scoped_refptr<IndexedDBCallbacks> callbacks, | 171 scoped_refptr<IndexedDBCallbacks> callbacks, |
141 const GURL& origin_url, | 172 const GURL& origin_url, |
142 const base::FilePath& data_directory) { | 173 const base::FilePath& data_directory, |
174 base::TaskRunner* task_runner) { | |
143 IDB_TRACE("IndexedDBFactory::GetDatabaseNames"); | 175 IDB_TRACE("IndexedDBFactory::GetDatabaseNames"); |
144 // TODO(dgrogan): Plumb data_loss back to script eventually? | 176 // TODO(dgrogan): Plumb data_loss back to script eventually? |
145 blink::WebIDBDataLoss data_loss; | 177 blink::WebIDBDataLoss data_loss; |
146 std::string data_loss_message; | 178 std::string data_loss_message; |
147 bool disk_full; | 179 bool disk_full; |
148 scoped_refptr<IndexedDBBackingStore> backing_store = | 180 scoped_refptr<IndexedDBBackingStore> backing_store = |
149 OpenBackingStore(origin_url, | 181 OpenBackingStore(origin_url, |
150 data_directory, | 182 data_directory, |
151 &data_loss, | 183 &data_loss, |
152 &data_loss_message, | 184 &data_loss_message, |
153 &disk_full); | 185 &disk_full, |
186 task_runner); | |
154 if (!backing_store) { | 187 if (!backing_store) { |
155 callbacks->OnError( | 188 callbacks->OnError( |
156 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | 189 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
157 "Internal error opening backing store for " | 190 "Internal error opening backing store for " |
158 "indexedDB.webkitGetDatabaseNames.")); | 191 "indexedDB.webkitGetDatabaseNames.")); |
159 return; | 192 return; |
160 } | 193 } |
161 | 194 |
162 callbacks->OnSuccess(backing_store->GetDatabaseNames()); | 195 callbacks->OnSuccess(backing_store->GetDatabaseNames()); |
163 backing_store = NULL; | 196 backing_store = NULL; |
164 ReleaseBackingStore(origin_url, false /* immediate */); | 197 ReleaseBackingStore(origin_url, false /* immediate */); |
165 } | 198 } |
166 | 199 |
167 void IndexedDBFactory::DeleteDatabase( | 200 void IndexedDBFactory::DeleteDatabase( |
168 const base::string16& name, | 201 const base::string16& name, |
169 scoped_refptr<IndexedDBCallbacks> callbacks, | 202 scoped_refptr<IndexedDBCallbacks> callbacks, |
170 const GURL& origin_url, | 203 const GURL& origin_url, |
171 const base::FilePath& data_directory) { | 204 const base::FilePath& data_directory, |
205 base::TaskRunner* task_runner) { | |
172 IDB_TRACE("IndexedDBFactory::DeleteDatabase"); | 206 IDB_TRACE("IndexedDBFactory::DeleteDatabase"); |
173 IndexedDBDatabase::Identifier unique_identifier(origin_url, name); | 207 IndexedDBDatabase::Identifier unique_identifier(origin_url, name); |
174 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); | 208 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); |
175 if (it != database_map_.end()) { | 209 if (it != database_map_.end()) { |
176 // If there are any connections to the database, directly delete the | 210 // If there are any connections to the database, directly delete the |
177 // database. | 211 // database. |
178 it->second->DeleteDatabase(callbacks); | 212 it->second->DeleteDatabase(callbacks); |
179 return; | 213 return; |
180 } | 214 } |
181 | 215 |
182 // TODO(dgrogan): Plumb data_loss back to script eventually? | 216 // TODO(dgrogan): Plumb data_loss back to script eventually? |
183 blink::WebIDBDataLoss data_loss; | 217 blink::WebIDBDataLoss data_loss; |
184 std::string data_loss_message; | 218 std::string data_loss_message; |
185 bool disk_full = false; | 219 bool disk_full = false; |
186 scoped_refptr<IndexedDBBackingStore> backing_store = | 220 scoped_refptr<IndexedDBBackingStore> backing_store = |
187 OpenBackingStore(origin_url, | 221 OpenBackingStore(origin_url, |
188 data_directory, | 222 data_directory, |
189 &data_loss, | 223 &data_loss, |
190 &data_loss_message, | 224 &data_loss_message, |
191 &disk_full); | 225 &disk_full, |
226 task_runner); | |
192 if (!backing_store) { | 227 if (!backing_store) { |
193 callbacks->OnError( | 228 callbacks->OnError( |
194 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | 229 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
195 ASCIIToUTF16( | 230 ASCIIToUTF16( |
196 "Internal error opening backing store " | 231 "Internal error opening backing store " |
197 "for indexedDB.deleteDatabase."))); | 232 "for indexedDB.deleteDatabase."))); |
198 return; | 233 return; |
199 } | 234 } |
200 | 235 |
201 scoped_refptr<IndexedDBDatabase> database = | 236 scoped_refptr<IndexedDBDatabase> database = |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
251 if (it == backing_store_map_.end()) | 286 if (it == backing_store_map_.end()) |
252 return false; | 287 return false; |
253 return it->second->close_timer()->IsRunning(); | 288 return it->second->close_timer()->IsRunning(); |
254 } | 289 } |
255 | 290 |
256 scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore( | 291 scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore( |
257 const GURL& origin_url, | 292 const GURL& origin_url, |
258 const base::FilePath& data_directory, | 293 const base::FilePath& data_directory, |
259 blink::WebIDBDataLoss* data_loss, | 294 blink::WebIDBDataLoss* data_loss, |
260 std::string* data_loss_message, | 295 std::string* data_loss_message, |
261 bool* disk_full) { | 296 bool* disk_full, |
297 base::TaskRunner* task_runner) { | |
262 const bool open_in_memory = data_directory.empty(); | 298 const bool open_in_memory = data_directory.empty(); |
263 | 299 |
264 IndexedDBBackingStoreMap::iterator it2 = backing_store_map_.find(origin_url); | 300 IndexedDBBackingStoreMap::iterator it2 = backing_store_map_.find(origin_url); |
265 if (it2 != backing_store_map_.end()) { | 301 if (it2 != backing_store_map_.end()) { |
266 it2->second->close_timer()->Stop(); | 302 it2->second->close_timer()->Stop(); |
267 return it2->second; | 303 return it2->second; |
268 } | 304 } |
269 | 305 |
270 scoped_refptr<IndexedDBBackingStore> backing_store; | 306 scoped_refptr<IndexedDBBackingStore> backing_store; |
271 if (open_in_memory) { | 307 if (open_in_memory) { |
272 backing_store = IndexedDBBackingStore::OpenInMemory(origin_url); | 308 backing_store = |
309 IndexedDBBackingStore::OpenInMemory(origin_url, task_runner); | |
273 } else { | 310 } else { |
274 backing_store = IndexedDBBackingStore::Open(origin_url, | 311 backing_store = IndexedDBBackingStore::Open(this, |
312 origin_url, | |
275 data_directory, | 313 data_directory, |
276 data_loss, | 314 data_loss, |
277 data_loss_message, | 315 data_loss_message, |
278 disk_full); | 316 disk_full, |
317 task_runner); | |
279 } | 318 } |
280 | 319 |
281 if (backing_store.get()) { | 320 if (backing_store.get()) { |
282 backing_store_map_[origin_url] = backing_store; | 321 backing_store_map_[origin_url] = backing_store; |
283 // If an in-memory database, bind lifetime to this factory instance. | 322 // If an in-memory database, bind lifetime to this factory instance. |
284 if (open_in_memory) | 323 if (open_in_memory) |
285 session_only_backing_stores_.insert(backing_store); | 324 session_only_backing_stores_.insert(backing_store); |
286 | 325 |
287 // All backing stores associated with this factory should be of the same | 326 // All backing stores associated with this factory should be of the same |
288 // type. | 327 // type. |
289 DCHECK(session_only_backing_stores_.empty() || open_in_memory); | 328 DCHECK(session_only_backing_stores_.empty() || open_in_memory); |
290 | 329 |
291 return backing_store; | 330 return backing_store; |
292 } | 331 } |
293 | 332 |
294 return 0; | 333 return 0; |
295 } | 334 } |
296 | 335 |
297 void IndexedDBFactory::Open(const base::string16& name, | 336 void IndexedDBFactory::Open(const base::string16& name, |
298 const IndexedDBPendingConnection& connection, | 337 const IndexedDBPendingConnection& connection, |
299 const GURL& origin_url, | 338 const GURL& origin_url, |
300 const base::FilePath& data_directory) { | 339 const base::FilePath& data_directory, |
340 base::TaskRunner* task_runner) { | |
301 IDB_TRACE("IndexedDBFactory::Open"); | 341 IDB_TRACE("IndexedDBFactory::Open"); |
302 scoped_refptr<IndexedDBDatabase> database; | 342 scoped_refptr<IndexedDBDatabase> database; |
303 IndexedDBDatabase::Identifier unique_identifier(origin_url, name); | 343 IndexedDBDatabase::Identifier unique_identifier(origin_url, name); |
304 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); | 344 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); |
305 blink::WebIDBDataLoss data_loss = | 345 blink::WebIDBDataLoss data_loss = |
306 blink::WebIDBDataLossNone; | 346 blink::WebIDBDataLossNone; |
307 std::string data_loss_message; | 347 std::string data_loss_message; |
308 bool disk_full = false; | 348 bool disk_full = false; |
309 bool was_open = (it != database_map_.end()); | 349 bool was_open = (it != database_map_.end()); |
310 if (!was_open) { | 350 if (!was_open) { |
311 scoped_refptr<IndexedDBBackingStore> backing_store = | 351 scoped_refptr<IndexedDBBackingStore> backing_store = |
312 OpenBackingStore(origin_url, | 352 OpenBackingStore(origin_url, |
313 data_directory, | 353 data_directory, |
314 &data_loss, | 354 &data_loss, |
315 &data_loss_message, | 355 &data_loss_message, |
316 &disk_full); | 356 &disk_full, |
357 task_runner); | |
317 if (!backing_store) { | 358 if (!backing_store) { |
318 if (disk_full) { | 359 if (disk_full) { |
319 connection.callbacks->OnError( | 360 connection.callbacks->OnError( |
320 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError, | 361 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError, |
321 ASCIIToUTF16( | 362 ASCIIToUTF16( |
322 "Encountered full disk while opening " | 363 "Encountered full disk while opening " |
323 "backing store for indexedDB.open."))); | 364 "backing store for indexedDB.open."))); |
324 return; | 365 return; |
325 } | 366 } |
326 connection.callbacks->OnError(IndexedDBDatabaseError( | 367 connection.callbacks->OnError(IndexedDBDatabaseError( |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
365 | 406 |
366 std::pair<OriginDBMapIterator, OriginDBMapIterator> range = | 407 std::pair<OriginDBMapIterator, OriginDBMapIterator> range = |
367 GetOpenDatabasesForOrigin(origin_url); | 408 GetOpenDatabasesForOrigin(origin_url); |
368 for (OriginDBMapIterator it = range.first; it != range.second; ++it) | 409 for (OriginDBMapIterator it = range.first; it != range.second; ++it) |
369 count += it->second->ConnectionCount(); | 410 count += it->second->ConnectionCount(); |
370 | 411 |
371 return count; | 412 return count; |
372 } | 413 } |
373 | 414 |
374 } // namespace content | 415 } // namespace content |
OLD | NEW |