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 "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 |