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_impl.h" | 5 #include "content/browser/indexed_db/indexed_db_factory_impl.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 DCHECK(!database_map_.find(identifier)->second->backing_store()); | 57 DCHECK(!database_map_.find(identifier)->second->backing_store()); |
| 58 | 58 |
| 59 RemoveDatabaseFromMaps(identifier); | 59 RemoveDatabaseFromMaps(identifier); |
| 60 | 60 |
| 61 // No grace period on a forced-close, as the initiator is | 61 // No grace period on a forced-close, as the initiator is |
| 62 // assuming the backing store will be released once all | 62 // assuming the backing store will be released once all |
| 63 // connections are closed. | 63 // connections are closed. |
| 64 ReleaseBackingStore(identifier.first, forced_close); | 64 ReleaseBackingStore(identifier.first, forced_close); |
| 65 } | 65 } |
| 66 | 66 |
| 67 void IndexedDBFactoryImpl::ReleaseBackingStore(const GURL& origin_url, | 67 void IndexedDBFactoryImpl::ReleaseBackingStore(const url::Origin& origin, |
| 68 bool immediate) { | 68 bool immediate) { |
| 69 if (immediate) { | 69 if (immediate) { |
| 70 IndexedDBBackingStoreMap::iterator it = | 70 IndexedDBBackingStoreMap::iterator it = |
| 71 backing_stores_with_active_blobs_.find(origin_url); | 71 backing_stores_with_active_blobs_.find(origin); |
| 72 if (it != backing_stores_with_active_blobs_.end()) { | 72 if (it != backing_stores_with_active_blobs_.end()) { |
| 73 it->second->active_blob_registry()->ForceShutdown(); | 73 it->second->active_blob_registry()->ForceShutdown(); |
| 74 backing_stores_with_active_blobs_.erase(it); | 74 backing_stores_with_active_blobs_.erase(it); |
| 75 } | 75 } |
| 76 } | 76 } |
| 77 | 77 |
| 78 // Only close if this is the last reference. | 78 // Only close if this is the last reference. |
| 79 if (!HasLastBackingStoreReference(origin_url)) | 79 if (!HasLastBackingStoreReference(origin)) |
| 80 return; | 80 return; |
| 81 | 81 |
| 82 // If this factory does hold the last reference to the backing store, it can | 82 // If this factory does hold the last reference to the backing store, it can |
| 83 // be closed - but unless requested to close it immediately, keep it around | 83 // be closed - but unless requested to close it immediately, keep it around |
| 84 // for a short period so that a re-open is fast. | 84 // for a short period so that a re-open is fast. |
| 85 if (immediate) { | 85 if (immediate) { |
| 86 CloseBackingStore(origin_url); | 86 CloseBackingStore(origin); |
| 87 return; | 87 return; |
| 88 } | 88 } |
| 89 | 89 |
| 90 // Start a timer to close the backing store, unless something else opens it | 90 // Start a timer to close the backing store, unless something else opens it |
| 91 // in the mean time. | 91 // in the mean time. |
| 92 DCHECK(!backing_store_map_[origin_url]->close_timer()->IsRunning()); | 92 DCHECK(!backing_store_map_[origin]->close_timer()->IsRunning()); |
| 93 backing_store_map_[origin_url]->close_timer()->Start( | 93 backing_store_map_[origin]->close_timer()->Start( |
| 94 FROM_HERE, | 94 FROM_HERE, base::TimeDelta::FromMilliseconds(kBackingStoreGracePeriodMs), |
| 95 base::TimeDelta::FromMilliseconds(kBackingStoreGracePeriodMs), | 95 base::Bind(&IndexedDBFactoryImpl::MaybeCloseBackingStore, this, origin)); |
| 96 base::Bind( | |
| 97 &IndexedDBFactoryImpl::MaybeCloseBackingStore, this, origin_url)); | |
| 98 } | 96 } |
| 99 | 97 |
| 100 void IndexedDBFactoryImpl::MaybeCloseBackingStore(const GURL& origin_url) { | 98 void IndexedDBFactoryImpl::MaybeCloseBackingStore(const url::Origin& origin) { |
| 101 // Another reference may have opened since the maybe-close was posted, so it | 99 // Another reference may have opened since the maybe-close was posted, so it |
| 102 // is necessary to check again. | 100 // is necessary to check again. |
| 103 if (HasLastBackingStoreReference(origin_url)) | 101 if (HasLastBackingStoreReference(origin)) |
| 104 CloseBackingStore(origin_url); | 102 CloseBackingStore(origin); |
| 105 } | 103 } |
| 106 | 104 |
| 107 void IndexedDBFactoryImpl::CloseBackingStore(const GURL& origin_url) { | 105 void IndexedDBFactoryImpl::CloseBackingStore(const url::Origin& origin) { |
| 108 IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin_url); | 106 IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin); |
| 109 DCHECK(it != backing_store_map_.end()); | 107 DCHECK(it != backing_store_map_.end()); |
| 110 // Stop the timer (if it's running) - this may happen if the timer was started | 108 // Stop the timer (if it's running) - this may happen if the timer was started |
| 111 // and then a forced close occurs. | 109 // and then a forced close occurs. |
| 112 it->second->close_timer()->Stop(); | 110 it->second->close_timer()->Stop(); |
| 113 backing_store_map_.erase(it); | 111 backing_store_map_.erase(it); |
| 114 } | 112 } |
| 115 | 113 |
| 116 bool IndexedDBFactoryImpl::HasLastBackingStoreReference( | 114 bool IndexedDBFactoryImpl::HasLastBackingStoreReference( |
| 117 const GURL& origin_url) const { | 115 const url::Origin& origin) const { |
| 118 IndexedDBBackingStore* ptr; | 116 IndexedDBBackingStore* ptr; |
| 119 { | 117 { |
| 120 // Scope so that the implicit scoped_refptr<> is freed. | 118 // Scope so that the implicit scoped_refptr<> is freed. |
| 121 IndexedDBBackingStoreMap::const_iterator it = | 119 IndexedDBBackingStoreMap::const_iterator it = |
| 122 backing_store_map_.find(origin_url); | 120 backing_store_map_.find(origin); |
| 123 DCHECK(it != backing_store_map_.end()); | 121 DCHECK(it != backing_store_map_.end()); |
| 124 ptr = it->second.get(); | 122 ptr = it->second.get(); |
| 125 } | 123 } |
| 126 return ptr->HasOneRef(); | 124 return ptr->HasOneRef(); |
| 127 } | 125 } |
| 128 | 126 |
| 129 void IndexedDBFactoryImpl::ForceClose(const GURL& origin_url) { | 127 void IndexedDBFactoryImpl::ForceClose(const url::Origin& origin) { |
| 130 OriginDBs range = GetOpenDatabasesForOrigin(origin_url); | 128 OriginDBs range = GetOpenDatabasesForOrigin(origin); |
| 131 | 129 |
| 132 while (range.first != range.second) { | 130 while (range.first != range.second) { |
| 133 IndexedDBDatabase* db = range.first->second; | 131 IndexedDBDatabase* db = range.first->second; |
| 134 ++range.first; | 132 ++range.first; |
| 135 db->ForceClose(); | 133 db->ForceClose(); |
| 136 } | 134 } |
| 137 | 135 |
| 138 if (backing_store_map_.find(origin_url) != backing_store_map_.end()) | 136 if (backing_store_map_.find(origin) != backing_store_map_.end()) |
| 139 ReleaseBackingStore(origin_url, true /* immediate */); | 137 ReleaseBackingStore(origin, true /* immediate */); |
| 140 } | 138 } |
| 141 | 139 |
| 142 void IndexedDBFactoryImpl::ContextDestroyed() { | 140 void IndexedDBFactoryImpl::ContextDestroyed() { |
| 143 // Timers on backing stores hold a reference to this factory. When the | 141 // Timers on backing stores hold a reference to this factory. When the |
| 144 // context (which nominally owns this factory) is destroyed during thread | 142 // context (which nominally owns this factory) is destroyed during thread |
| 145 // termination the timers must be stopped so that this factory and the | 143 // termination the timers must be stopped so that this factory and the |
| 146 // stores can be disposed of. | 144 // stores can be disposed of. |
| 147 for (const auto& it : backing_store_map_) | 145 for (const auto& it : backing_store_map_) |
| 148 it.second->close_timer()->Stop(); | 146 it.second->close_timer()->Stop(); |
| 149 backing_store_map_.clear(); | 147 backing_store_map_.clear(); |
| 150 backing_stores_with_active_blobs_.clear(); | 148 backing_stores_with_active_blobs_.clear(); |
| 151 context_ = NULL; | 149 context_ = NULL; |
| 152 } | 150 } |
| 153 | 151 |
| 154 void IndexedDBFactoryImpl::ReportOutstandingBlobs(const GURL& origin_url, | 152 void IndexedDBFactoryImpl::ReportOutstandingBlobs(const url::Origin& origin, |
| 155 bool blobs_outstanding) { | 153 bool blobs_outstanding) { |
| 156 if (!context_) | 154 if (!context_) |
| 157 return; | 155 return; |
| 158 if (blobs_outstanding) { | 156 if (blobs_outstanding) { |
| 159 DCHECK(!backing_stores_with_active_blobs_.count(origin_url)); | 157 DCHECK(!backing_stores_with_active_blobs_.count(origin)); |
| 160 IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin_url); | 158 IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin); |
| 161 if (it != backing_store_map_.end()) | 159 if (it != backing_store_map_.end()) |
| 162 backing_stores_with_active_blobs_.insert(*it); | 160 backing_stores_with_active_blobs_.insert(*it); |
| 163 else | 161 else |
| 164 DCHECK(false); | 162 DCHECK(false); |
| 165 } else { | 163 } else { |
| 166 IndexedDBBackingStoreMap::iterator it = | 164 IndexedDBBackingStoreMap::iterator it = |
| 167 backing_stores_with_active_blobs_.find(origin_url); | 165 backing_stores_with_active_blobs_.find(origin); |
| 168 if (it != backing_stores_with_active_blobs_.end()) { | 166 if (it != backing_stores_with_active_blobs_.end()) { |
| 169 backing_stores_with_active_blobs_.erase(it); | 167 backing_stores_with_active_blobs_.erase(it); |
| 170 ReleaseBackingStore(origin_url, false /* immediate */); | 168 ReleaseBackingStore(origin, false /* immediate */); |
| 171 } | 169 } |
| 172 } | 170 } |
| 173 } | 171 } |
| 174 | 172 |
| 175 void IndexedDBFactoryImpl::GetDatabaseNames( | 173 void IndexedDBFactoryImpl::GetDatabaseNames( |
| 176 scoped_refptr<IndexedDBCallbacks> callbacks, | 174 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 177 const url::Origin& origin, | 175 const url::Origin& origin, |
| 178 const base::FilePath& data_directory, | 176 const base::FilePath& data_directory, |
| 179 net::URLRequestContext* request_context) { | 177 net::URLRequestContext* request_context) { |
| 180 IDB_TRACE("IndexedDBFactoryImpl::GetDatabaseNames"); | 178 IDB_TRACE("IndexedDBFactoryImpl::GetDatabaseNames"); |
| 181 // TODO(dgrogan): Plumb data_loss back to script eventually? | 179 // TODO(dgrogan): Plumb data_loss back to script eventually? |
| 182 blink::WebIDBDataLoss data_loss; | 180 blink::WebIDBDataLoss data_loss; |
| 183 std::string data_loss_message; | 181 std::string data_loss_message; |
| 184 bool disk_full; | 182 bool disk_full; |
| 185 GURL origin_url(origin.Serialize()); | |
| 186 leveldb::Status s; | 183 leveldb::Status s; |
| 187 // TODO(cmumford): Handle this error | 184 // TODO(cmumford): Handle this error |
| 188 scoped_refptr<IndexedDBBackingStore> backing_store = | 185 scoped_refptr<IndexedDBBackingStore> backing_store = |
| 189 OpenBackingStore(origin_url, | 186 OpenBackingStore(origin, data_directory, request_context, &data_loss, |
| 190 data_directory, | 187 &data_loss_message, &disk_full, &s); |
| 191 request_context, | |
| 192 &data_loss, | |
| 193 &data_loss_message, | |
| 194 &disk_full, | |
| 195 &s); | |
| 196 if (!backing_store.get()) { | 188 if (!backing_store.get()) { |
| 197 callbacks->OnError( | 189 callbacks->OnError( |
| 198 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | 190 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
| 199 "Internal error opening backing store for " | 191 "Internal error opening backing store for " |
| 200 "indexedDB.webkitGetDatabaseNames.")); | 192 "indexedDB.webkitGetDatabaseNames.")); |
| 201 return; | 193 return; |
| 202 } | 194 } |
| 203 | 195 |
| 204 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); | 196 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); |
| 205 if (!s.ok()) { | 197 if (!s.ok()) { |
| 206 DLOG(ERROR) << "Internal error getting database names"; | 198 DLOG(ERROR) << "Internal error getting database names"; |
| 207 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 199 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
| 208 "Internal error opening backing store for " | 200 "Internal error opening backing store for " |
| 209 "indexedDB.webkitGetDatabaseNames."); | 201 "indexedDB.webkitGetDatabaseNames."); |
| 210 callbacks->OnError(error); | 202 callbacks->OnError(error); |
| 211 backing_store = NULL; | 203 backing_store = NULL; |
| 212 if (s.IsCorruption()) | 204 if (s.IsCorruption()) |
| 213 HandleBackingStoreCorruption(origin_url, error); | 205 HandleBackingStoreCorruption(origin, error); |
| 214 return; | 206 return; |
| 215 } | 207 } |
| 216 callbacks->OnSuccess(names); | 208 callbacks->OnSuccess(names); |
| 217 backing_store = NULL; | 209 backing_store = NULL; |
| 218 ReleaseBackingStore(origin_url, false /* immediate */); | 210 ReleaseBackingStore(origin, false /* immediate */); |
| 219 } | 211 } |
| 220 | 212 |
| 221 void IndexedDBFactoryImpl::DeleteDatabase( | 213 void IndexedDBFactoryImpl::DeleteDatabase( |
| 222 const base::string16& name, | 214 const base::string16& name, |
| 223 net::URLRequestContext* request_context, | 215 net::URLRequestContext* request_context, |
| 224 scoped_refptr<IndexedDBCallbacks> callbacks, | 216 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 225 const url::Origin& origin, | 217 const url::Origin& origin, |
| 226 const base::FilePath& data_directory) { | 218 const base::FilePath& data_directory) { |
| 227 IDB_TRACE("IndexedDBFactoryImpl::DeleteDatabase"); | 219 IDB_TRACE("IndexedDBFactoryImpl::DeleteDatabase"); |
| 228 GURL origin_url(origin.Serialize()); | 220 IndexedDBDatabase::Identifier unique_identifier(origin, name); |
| 229 IndexedDBDatabase::Identifier unique_identifier(origin_url, name); | |
| 230 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); | 221 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); |
| 231 if (it != database_map_.end()) { | 222 if (it != database_map_.end()) { |
| 232 // If there are any connections to the database, directly delete the | 223 // If there are any connections to the database, directly delete the |
| 233 // database. | 224 // database. |
| 234 it->second->DeleteDatabase(callbacks); | 225 it->second->DeleteDatabase(callbacks); |
| 235 return; | 226 return; |
| 236 } | 227 } |
| 237 | 228 |
| 238 // TODO(dgrogan): Plumb data_loss back to script eventually? | 229 // TODO(dgrogan): Plumb data_loss back to script eventually? |
| 239 blink::WebIDBDataLoss data_loss; | 230 blink::WebIDBDataLoss data_loss; |
| 240 std::string data_loss_message; | 231 std::string data_loss_message; |
| 241 bool disk_full = false; | 232 bool disk_full = false; |
| 242 leveldb::Status s; | 233 leveldb::Status s; |
| 243 scoped_refptr<IndexedDBBackingStore> backing_store = | 234 scoped_refptr<IndexedDBBackingStore> backing_store = |
| 244 OpenBackingStore(origin_url, | 235 OpenBackingStore(origin, data_directory, request_context, &data_loss, |
| 245 data_directory, | 236 &data_loss_message, &disk_full, &s); |
| 246 request_context, | |
| 247 &data_loss, | |
| 248 &data_loss_message, | |
| 249 &disk_full, | |
| 250 &s); | |
| 251 if (!backing_store.get()) { | 237 if (!backing_store.get()) { |
| 252 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 238 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
| 253 ASCIIToUTF16( | 239 ASCIIToUTF16( |
| 254 "Internal error opening backing store " | 240 "Internal error opening backing store " |
| 255 "for indexedDB.deleteDatabase.")); | 241 "for indexedDB.deleteDatabase.")); |
| 256 callbacks->OnError(error); | 242 callbacks->OnError(error); |
| 257 if (s.IsCorruption()) { | 243 if (s.IsCorruption()) { |
| 258 HandleBackingStoreCorruption(origin_url, error); | 244 HandleBackingStoreCorruption(origin, error); |
| 259 } | 245 } |
| 260 return; | 246 return; |
| 261 } | 247 } |
| 262 | 248 |
| 263 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); | 249 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); |
| 264 if (!s.ok()) { | 250 if (!s.ok()) { |
| 265 DLOG(ERROR) << "Internal error getting database names"; | 251 DLOG(ERROR) << "Internal error getting database names"; |
| 266 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 252 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
| 267 "Internal error opening backing store for " | 253 "Internal error opening backing store for " |
| 268 "indexedDB.deleteDatabase."); | 254 "indexedDB.deleteDatabase."); |
| 269 callbacks->OnError(error); | 255 callbacks->OnError(error); |
| 270 backing_store = NULL; | 256 backing_store = NULL; |
| 271 if (s.IsCorruption()) | 257 if (s.IsCorruption()) |
| 272 HandleBackingStoreCorruption(origin_url, error); | 258 HandleBackingStoreCorruption(origin, error); |
| 273 return; | 259 return; |
| 274 } | 260 } |
| 275 if (!ContainsValue(names, name)) { | 261 if (!ContainsValue(names, name)) { |
| 276 const int64_t version = 0; | 262 const int64_t version = 0; |
| 277 callbacks->OnSuccess(version); | 263 callbacks->OnSuccess(version); |
| 278 backing_store = NULL; | 264 backing_store = NULL; |
| 279 ReleaseBackingStore(origin_url, false /* immediate */); | 265 ReleaseBackingStore(origin, false /* immediate */); |
| 280 return; | 266 return; |
| 281 } | 267 } |
| 282 | 268 |
| 283 scoped_refptr<IndexedDBDatabase> database = IndexedDBDatabase::Create( | 269 scoped_refptr<IndexedDBDatabase> database = IndexedDBDatabase::Create( |
| 284 name, backing_store.get(), this, unique_identifier, &s); | 270 name, backing_store.get(), this, unique_identifier, &s); |
| 285 if (!database.get()) { | 271 if (!database.get()) { |
| 286 IndexedDBDatabaseError error( | 272 IndexedDBDatabaseError error( |
| 287 blink::WebIDBDatabaseExceptionUnknownError, | 273 blink::WebIDBDatabaseExceptionUnknownError, |
| 288 ASCIIToUTF16( | 274 ASCIIToUTF16( |
| 289 "Internal error creating database backend for " | 275 "Internal error creating database backend for " |
| 290 "indexedDB.deleteDatabase.")); | 276 "indexedDB.deleteDatabase.")); |
| 291 callbacks->OnError(error); | 277 callbacks->OnError(error); |
| 292 if (s.IsCorruption()) { | 278 if (s.IsCorruption()) { |
| 293 backing_store = NULL; | 279 backing_store = NULL; |
| 294 HandleBackingStoreCorruption(origin_url, error); | 280 HandleBackingStoreCorruption(origin, error); |
| 295 } | 281 } |
| 296 return; | 282 return; |
| 297 } | 283 } |
| 298 | 284 |
| 299 database_map_[unique_identifier] = database.get(); | 285 database_map_[unique_identifier] = database.get(); |
| 300 origin_dbs_.insert(std::make_pair(origin_url, database.get())); | 286 origin_dbs_.insert(std::make_pair(origin, database.get())); |
| 301 database->DeleteDatabase(callbacks); | 287 database->DeleteDatabase(callbacks); |
| 302 RemoveDatabaseFromMaps(unique_identifier); | 288 RemoveDatabaseFromMaps(unique_identifier); |
| 303 database = NULL; | 289 database = NULL; |
| 304 backing_store = NULL; | 290 backing_store = NULL; |
| 305 ReleaseBackingStore(origin_url, false /* immediate */); | 291 ReleaseBackingStore(origin, false /* immediate */); |
| 306 } | 292 } |
| 307 | 293 |
| 308 void IndexedDBFactoryImpl::DatabaseDeleted( | 294 void IndexedDBFactoryImpl::DatabaseDeleted( |
| 309 const IndexedDBDatabase::Identifier& identifier) { | 295 const IndexedDBDatabase::Identifier& identifier) { |
| 310 // NULL after ContextDestroyed() called, and in some unit tests. | 296 // NULL after ContextDestroyed() called, and in some unit tests. |
| 311 if (!context_) | 297 if (!context_) |
| 312 return; | 298 return; |
| 313 context_->DatabaseDeleted(identifier.first); | 299 context_->DatabaseDeleted(identifier.first); |
| 314 } | 300 } |
| 315 | 301 |
| 316 void IndexedDBFactoryImpl::HandleBackingStoreFailure(const GURL& origin_url) { | 302 void IndexedDBFactoryImpl::HandleBackingStoreFailure( |
| 303 const url::Origin& origin) { | |
|
cmumford
2016/03/31 20:54:16
What about adding
using url::Origin;
at the top
jsbell
2016/04/01 20:31:35
Done.
| |
| 317 // NULL after ContextDestroyed() called, and in some unit tests. | 304 // NULL after ContextDestroyed() called, and in some unit tests. |
| 318 if (!context_) | 305 if (!context_) |
| 319 return; | 306 return; |
| 320 context_->ForceClose(origin_url, | 307 context_->ForceClose(origin, |
| 321 IndexedDBContextImpl::FORCE_CLOSE_BACKING_STORE_FAILURE); | 308 IndexedDBContextImpl::FORCE_CLOSE_BACKING_STORE_FAILURE); |
| 322 } | 309 } |
| 323 | 310 |
| 324 void IndexedDBFactoryImpl::HandleBackingStoreCorruption( | 311 void IndexedDBFactoryImpl::HandleBackingStoreCorruption( |
| 325 const GURL& origin_url, | 312 const url::Origin& origin, |
| 326 const IndexedDBDatabaseError& error) { | 313 const IndexedDBDatabaseError& error) { |
| 327 // Make a copy of origin_url as this is likely a reference to a member of a | 314 // Make a copy of origin as this is likely a reference to a member of a |
| 328 // backing store which this function will be deleting. | 315 // backing store which this function will be deleting. |
| 329 GURL saved_origin_url(origin_url); | 316 url::Origin saved_origin(origin); |
| 330 DCHECK(context_); | 317 DCHECK(context_); |
| 331 base::FilePath path_base = context_->data_path(); | 318 base::FilePath path_base = context_->data_path(); |
| 332 IndexedDBBackingStore::RecordCorruptionInfo( | 319 IndexedDBBackingStore::RecordCorruptionInfo( |
| 333 path_base, saved_origin_url, base::UTF16ToUTF8(error.message())); | 320 path_base, saved_origin, base::UTF16ToUTF8(error.message())); |
| 334 HandleBackingStoreFailure(saved_origin_url); | 321 HandleBackingStoreFailure(saved_origin); |
| 335 // Note: DestroyBackingStore only deletes LevelDB files, leaving all others, | 322 // Note: DestroyBackingStore only deletes LevelDB files, leaving all others, |
| 336 // so our corruption info file will remain. | 323 // so our corruption info file will remain. |
| 337 leveldb::Status s = | 324 leveldb::Status s = |
| 338 IndexedDBBackingStore::DestroyBackingStore(path_base, saved_origin_url); | 325 IndexedDBBackingStore::DestroyBackingStore(path_base, saved_origin); |
| 339 if (!s.ok()) | 326 if (!s.ok()) |
| 340 DLOG(ERROR) << "Unable to delete backing store: " << s.ToString(); | 327 DLOG(ERROR) << "Unable to delete backing store: " << s.ToString(); |
| 341 } | 328 } |
| 342 | 329 |
| 343 bool IndexedDBFactoryImpl::IsDatabaseOpen(const GURL& origin_url, | 330 bool IndexedDBFactoryImpl::IsDatabaseOpen(const url::Origin& origin, |
| 344 const base::string16& name) const { | 331 const base::string16& name) const { |
| 345 return !!database_map_.count(IndexedDBDatabase::Identifier(origin_url, name)); | 332 return !!database_map_.count(IndexedDBDatabase::Identifier(origin, name)); |
| 346 } | 333 } |
| 347 | 334 |
| 348 bool IndexedDBFactoryImpl::IsBackingStoreOpen(const GURL& origin_url) const { | 335 bool IndexedDBFactoryImpl::IsBackingStoreOpen(const url::Origin& origin) const { |
| 349 return backing_store_map_.find(origin_url) != backing_store_map_.end(); | 336 return backing_store_map_.find(origin) != backing_store_map_.end(); |
| 350 } | 337 } |
| 351 | 338 |
| 352 bool IndexedDBFactoryImpl::IsBackingStorePendingClose( | 339 bool IndexedDBFactoryImpl::IsBackingStorePendingClose( |
| 353 const GURL& origin_url) const { | 340 const url::Origin& origin) const { |
| 354 IndexedDBBackingStoreMap::const_iterator it = | 341 IndexedDBBackingStoreMap::const_iterator it = backing_store_map_.find(origin); |
| 355 backing_store_map_.find(origin_url); | |
| 356 if (it == backing_store_map_.end()) | 342 if (it == backing_store_map_.end()) |
| 357 return false; | 343 return false; |
| 358 return it->second->close_timer()->IsRunning(); | 344 return it->second->close_timer()->IsRunning(); |
| 359 } | 345 } |
| 360 | 346 |
| 361 scoped_refptr<IndexedDBBackingStore> | 347 scoped_refptr<IndexedDBBackingStore> |
| 362 IndexedDBFactoryImpl::OpenBackingStoreHelper( | 348 IndexedDBFactoryImpl::OpenBackingStoreHelper( |
| 363 const GURL& origin_url, | 349 const url::Origin& origin, |
| 364 const base::FilePath& data_directory, | 350 const base::FilePath& data_directory, |
| 365 net::URLRequestContext* request_context, | 351 net::URLRequestContext* request_context, |
| 366 blink::WebIDBDataLoss* data_loss, | 352 blink::WebIDBDataLoss* data_loss, |
| 367 std::string* data_loss_message, | 353 std::string* data_loss_message, |
| 368 bool* disk_full, | 354 bool* disk_full, |
| 369 bool first_time, | 355 bool first_time, |
| 370 leveldb::Status* status) { | 356 leveldb::Status* status) { |
| 371 return IndexedDBBackingStore::Open(this, | 357 return IndexedDBBackingStore::Open( |
| 372 origin_url, | 358 this, origin, data_directory, request_context, data_loss, |
| 373 data_directory, | 359 data_loss_message, disk_full, context_->TaskRunner(), first_time, status); |
| 374 request_context, | |
| 375 data_loss, | |
| 376 data_loss_message, | |
| 377 disk_full, | |
| 378 context_->TaskRunner(), | |
| 379 first_time, | |
| 380 status); | |
| 381 } | 360 } |
| 382 | 361 |
| 383 scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore( | 362 scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore( |
| 384 const GURL& origin_url, | 363 const url::Origin& origin, |
| 385 const base::FilePath& data_directory, | 364 const base::FilePath& data_directory, |
| 386 net::URLRequestContext* request_context, | 365 net::URLRequestContext* request_context, |
| 387 blink::WebIDBDataLoss* data_loss, | 366 blink::WebIDBDataLoss* data_loss, |
| 388 std::string* data_loss_message, | 367 std::string* data_loss_message, |
| 389 bool* disk_full, | 368 bool* disk_full, |
| 390 leveldb::Status* status) { | 369 leveldb::Status* status) { |
| 391 const bool open_in_memory = data_directory.empty(); | 370 const bool open_in_memory = data_directory.empty(); |
| 392 | 371 |
| 393 IndexedDBBackingStoreMap::iterator it2 = backing_store_map_.find(origin_url); | 372 IndexedDBBackingStoreMap::iterator it2 = backing_store_map_.find(origin); |
| 394 if (it2 != backing_store_map_.end()) { | 373 if (it2 != backing_store_map_.end()) { |
| 395 it2->second->close_timer()->Stop(); | 374 it2->second->close_timer()->Stop(); |
| 396 return it2->second; | 375 return it2->second; |
| 397 } | 376 } |
| 398 | 377 |
| 399 scoped_refptr<IndexedDBBackingStore> backing_store; | 378 scoped_refptr<IndexedDBBackingStore> backing_store; |
| 400 bool first_time = false; | 379 bool first_time = false; |
| 401 if (open_in_memory) { | 380 if (open_in_memory) { |
| 402 backing_store = IndexedDBBackingStore::OpenInMemory( | 381 backing_store = IndexedDBBackingStore::OpenInMemory( |
| 403 origin_url, context_->TaskRunner(), status); | 382 origin, context_->TaskRunner(), status); |
| 404 } else { | 383 } else { |
| 405 first_time = !backends_opened_since_boot_.count(origin_url); | 384 first_time = !backends_opened_since_boot_.count(origin); |
| 406 | 385 |
| 407 backing_store = OpenBackingStoreHelper(origin_url, | 386 backing_store = OpenBackingStoreHelper( |
| 408 data_directory, | 387 origin, data_directory, request_context, data_loss, data_loss_message, |
| 409 request_context, | 388 disk_full, first_time, status); |
| 410 data_loss, | |
| 411 data_loss_message, | |
| 412 disk_full, | |
| 413 first_time, | |
| 414 status); | |
| 415 } | 389 } |
| 416 | 390 |
| 417 if (backing_store.get()) { | 391 if (backing_store.get()) { |
| 418 if (first_time) | 392 if (first_time) |
| 419 backends_opened_since_boot_.insert(origin_url); | 393 backends_opened_since_boot_.insert(origin); |
| 420 backing_store_map_[origin_url] = backing_store; | 394 backing_store_map_[origin] = backing_store; |
| 421 // If an in-memory database, bind lifetime to this factory instance. | 395 // If an in-memory database, bind lifetime to this factory instance. |
| 422 if (open_in_memory) | 396 if (open_in_memory) |
| 423 session_only_backing_stores_.insert(backing_store); | 397 session_only_backing_stores_.insert(backing_store); |
| 424 | 398 |
| 425 // All backing stores associated with this factory should be of the same | 399 // All backing stores associated with this factory should be of the same |
| 426 // type. | 400 // type. |
| 427 DCHECK_NE(session_only_backing_stores_.empty(), open_in_memory); | 401 DCHECK_NE(session_only_backing_stores_.empty(), open_in_memory); |
| 428 | 402 |
| 429 return backing_store; | 403 return backing_store; |
| 430 } | 404 } |
| 431 | 405 |
| 432 return 0; | 406 return 0; |
| 433 } | 407 } |
| 434 | 408 |
| 435 void IndexedDBFactoryImpl::Open(const base::string16& name, | 409 void IndexedDBFactoryImpl::Open(const base::string16& name, |
| 436 const IndexedDBPendingConnection& connection, | 410 const IndexedDBPendingConnection& connection, |
| 437 net::URLRequestContext* request_context, | 411 net::URLRequestContext* request_context, |
| 438 const url::Origin& origin, | 412 const url::Origin& origin, |
| 439 const base::FilePath& data_directory) { | 413 const base::FilePath& data_directory) { |
| 440 IDB_TRACE("IndexedDBFactoryImpl::Open"); | 414 IDB_TRACE("IndexedDBFactoryImpl::Open"); |
| 441 scoped_refptr<IndexedDBDatabase> database; | 415 scoped_refptr<IndexedDBDatabase> database; |
| 442 GURL origin_url(origin.Serialize()); | 416 IndexedDBDatabase::Identifier unique_identifier(origin, name); |
| 443 IndexedDBDatabase::Identifier unique_identifier(origin_url, name); | |
| 444 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); | 417 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); |
| 445 blink::WebIDBDataLoss data_loss = | 418 blink::WebIDBDataLoss data_loss = |
| 446 blink::WebIDBDataLossNone; | 419 blink::WebIDBDataLossNone; |
| 447 std::string data_loss_message; | 420 std::string data_loss_message; |
| 448 bool disk_full = false; | 421 bool disk_full = false; |
| 449 bool was_open = (it != database_map_.end()); | 422 bool was_open = (it != database_map_.end()); |
| 450 if (!was_open) { | 423 if (!was_open) { |
| 451 leveldb::Status s; | 424 leveldb::Status s; |
| 452 scoped_refptr<IndexedDBBackingStore> backing_store = | 425 scoped_refptr<IndexedDBBackingStore> backing_store = |
| 453 OpenBackingStore(origin_url, | 426 OpenBackingStore(origin, data_directory, request_context, &data_loss, |
| 454 data_directory, | 427 &data_loss_message, &disk_full, &s); |
| 455 request_context, | |
| 456 &data_loss, | |
| 457 &data_loss_message, | |
| 458 &disk_full, | |
| 459 &s); | |
| 460 if (!backing_store.get()) { | 428 if (!backing_store.get()) { |
| 461 if (disk_full) { | 429 if (disk_full) { |
| 462 connection.callbacks->OnError( | 430 connection.callbacks->OnError( |
| 463 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError, | 431 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError, |
| 464 ASCIIToUTF16( | 432 ASCIIToUTF16( |
| 465 "Encountered full disk while opening " | 433 "Encountered full disk while opening " |
| 466 "backing store for indexedDB.open."))); | 434 "backing store for indexedDB.open."))); |
| 467 return; | 435 return; |
| 468 } | 436 } |
| 469 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 437 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
| 470 ASCIIToUTF16( | 438 ASCIIToUTF16( |
| 471 "Internal error opening backing store" | 439 "Internal error opening backing store" |
| 472 " for indexedDB.open.")); | 440 " for indexedDB.open.")); |
| 473 connection.callbacks->OnError(error); | 441 connection.callbacks->OnError(error); |
| 474 if (s.IsCorruption()) { | 442 if (s.IsCorruption()) { |
| 475 HandleBackingStoreCorruption(origin_url, error); | 443 HandleBackingStoreCorruption(origin, error); |
| 476 } | 444 } |
| 477 return; | 445 return; |
| 478 } | 446 } |
| 479 | 447 |
| 480 database = IndexedDBDatabase::Create( | 448 database = IndexedDBDatabase::Create( |
| 481 name, backing_store.get(), this, unique_identifier, &s); | 449 name, backing_store.get(), this, unique_identifier, &s); |
| 482 if (!database.get()) { | 450 if (!database.get()) { |
| 483 DLOG(ERROR) << "Unable to create the database"; | 451 DLOG(ERROR) << "Unable to create the database"; |
| 484 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 452 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
| 485 ASCIIToUTF16( | 453 ASCIIToUTF16( |
| 486 "Internal error creating " | 454 "Internal error creating " |
| 487 "database backend for " | 455 "database backend for " |
| 488 "indexedDB.open.")); | 456 "indexedDB.open.")); |
| 489 connection.callbacks->OnError(error); | 457 connection.callbacks->OnError(error); |
| 490 if (s.IsCorruption()) { | 458 if (s.IsCorruption()) { |
| 491 backing_store = NULL; // Closes the LevelDB so that it can be deleted | 459 backing_store = NULL; // Closes the LevelDB so that it can be deleted |
| 492 HandleBackingStoreCorruption(origin_url, error); | 460 HandleBackingStoreCorruption(origin, error); |
| 493 } | 461 } |
| 494 return; | 462 return; |
| 495 } | 463 } |
| 496 } else { | 464 } else { |
| 497 database = it->second; | 465 database = it->second; |
| 498 } | 466 } |
| 499 | 467 |
| 500 if (data_loss != blink::WebIDBDataLossNone) | 468 if (data_loss != blink::WebIDBDataLossNone) |
| 501 connection.callbacks->OnDataLoss(data_loss, data_loss_message); | 469 connection.callbacks->OnDataLoss(data_loss, data_loss_message); |
| 502 | 470 |
| 503 database->OpenConnection(connection); | 471 database->OpenConnection(connection); |
| 504 | 472 |
| 505 if (!was_open && database->ConnectionCount() > 0) { | 473 if (!was_open && database->ConnectionCount() > 0) { |
| 506 database_map_[unique_identifier] = database.get(); | 474 database_map_[unique_identifier] = database.get(); |
| 507 origin_dbs_.insert(std::make_pair(origin_url, database.get())); | 475 origin_dbs_.insert(std::make_pair(origin, database.get())); |
| 508 } | 476 } |
| 509 } | 477 } |
| 510 | 478 |
| 511 std::pair<IndexedDBFactoryImpl::OriginDBMapIterator, | 479 std::pair<IndexedDBFactoryImpl::OriginDBMapIterator, |
| 512 IndexedDBFactoryImpl::OriginDBMapIterator> | 480 IndexedDBFactoryImpl::OriginDBMapIterator> |
| 513 IndexedDBFactoryImpl::GetOpenDatabasesForOrigin(const GURL& origin_url) const { | 481 IndexedDBFactoryImpl::GetOpenDatabasesForOrigin( |
| 514 return origin_dbs_.equal_range(origin_url); | 482 const url::Origin& origin) const { |
| 483 return origin_dbs_.equal_range(origin); | |
| 515 } | 484 } |
| 516 | 485 |
| 517 size_t IndexedDBFactoryImpl::GetConnectionCount(const GURL& origin_url) const { | 486 size_t IndexedDBFactoryImpl::GetConnectionCount( |
| 487 const url::Origin& origin) const { | |
| 518 size_t count(0); | 488 size_t count(0); |
| 519 | 489 |
| 520 OriginDBs range = GetOpenDatabasesForOrigin(origin_url); | 490 OriginDBs range = GetOpenDatabasesForOrigin(origin); |
| 521 for (OriginDBMapIterator it = range.first; it != range.second; ++it) | 491 for (OriginDBMapIterator it = range.first; it != range.second; ++it) |
| 522 count += it->second->ConnectionCount(); | 492 count += it->second->ConnectionCount(); |
| 523 | 493 |
| 524 return count; | 494 return count; |
| 525 } | 495 } |
| 526 | 496 |
| 527 } // namespace content | 497 } // namespace content |
| OLD | NEW |