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

Side by Side Diff: content/browser/indexed_db/indexed_db_factory.cc

Issue 18023022: Blob support for IDB [Chromium] (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Handle the rest of Josh's feedback. Created 7 years 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) 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 22 matching lines...) Expand all
33 database_map_.erase(it); 33 database_map_.erase(it);
34 34
35 // No grace period on a forced-close, as the initiator is 35 // No grace period on a forced-close, as the initiator is
36 // assuming the backing store will be released once all 36 // assuming the backing store will be released once all
37 // connections are closed. 37 // connections are closed.
38 ReleaseBackingStore(origin_url, forcedClose); 38 ReleaseBackingStore(origin_url, forcedClose);
39 } 39 }
40 40
41 void IndexedDBFactory::ReleaseBackingStore(const GURL& origin_url, 41 void IndexedDBFactory::ReleaseBackingStore(const GURL& origin_url,
42 bool immediate) { 42 bool immediate) {
43 if (immediate) {
44 IndexedDBBackingStoreMap::iterator it =
45 backing_stores_with_active_blobs_.find(origin_url);
46 if (it != backing_stores_with_active_blobs_.end()) {
47 it->second->active_blob_registry()->ForceShutdown();
48 backing_stores_with_active_blobs_.erase(it);
49 }
50 }
51
43 // Only close if this is the last reference. 52 // Only close if this is the last reference.
44 if (!HasLastBackingStoreReference(origin_url)) 53 if (!HasLastBackingStoreReference(origin_url))
45 return; 54 return;
46 55
47 // If this factory does hold the last reference to the backing store, it can 56 // If this factory does hold the last reference to the backing store, it can
48 // be closed - but unless requested to close it immediately, keep it around 57 // be closed - but unless requested to close it immediately, keep it around
49 // for a short period so that a re-open is fast. 58 // for a short period so that a re-open is fast.
50 if (immediate) { 59 if (immediate) {
51 CloseBackingStore(origin_url); 60 CloseBackingStore(origin_url);
52 return; 61 return;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 void IndexedDBFactory::ContextDestroyed() { 102 void IndexedDBFactory::ContextDestroyed() {
94 // Timers on backing stores hold a reference to this factory. When the 103 // Timers on backing stores hold a reference to this factory. When the
95 // context (which nominally owns this factory) is destroyed during thread 104 // context (which nominally owns this factory) is destroyed during thread
96 // termination the timers must be stopped so that this factory and the 105 // termination the timers must be stopped so that this factory and the
97 // stores can be disposed of. 106 // stores can be disposed of.
98 for (IndexedDBBackingStoreMap::iterator it = backing_store_map_.begin(); 107 for (IndexedDBBackingStoreMap::iterator it = backing_store_map_.begin();
99 it != backing_store_map_.end(); 108 it != backing_store_map_.end();
100 ++it) 109 ++it)
101 it->second->close_timer()->Stop(); 110 it->second->close_timer()->Stop();
102 backing_store_map_.clear(); 111 backing_store_map_.clear();
112 backing_stores_with_active_blobs_.clear();
103 context_ = NULL; 113 context_ = NULL;
104 } 114 }
105 115
116 void IndexedDBFactory::ReportOutstandingBlobs(const GURL& origin_url,
jsbell 2013/12/20 00:44:20 To untangle this spaghetti, I'd like to turn the f
117 bool blobs_outstanding) {
118 if (!context_)
119 return;
120 if (blobs_outstanding) {
121 DCHECK(!backing_stores_with_active_blobs_.count(origin_url));
122 IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin_url);
123 if (it != backing_store_map_.end())
124 backing_stores_with_active_blobs_.insert(*it);
125 else
126 DCHECK(false);
127 } else {
128 IndexedDBBackingStoreMap::iterator it =
129 backing_stores_with_active_blobs_.find(origin_url);
130 if (it != backing_stores_with_active_blobs_.end()) {
131 backing_stores_with_active_blobs_.erase(it);
132 ReleaseBackingStore(origin_url, false);
133 }
134 }
135 }
136
106 void IndexedDBFactory::GetDatabaseNames( 137 void IndexedDBFactory::GetDatabaseNames(
107 scoped_refptr<IndexedDBCallbacks> callbacks, 138 scoped_refptr<IndexedDBCallbacks> callbacks,
108 const GURL& origin_url, 139 const GURL& origin_url,
109 const base::FilePath& data_directory) { 140 const base::FilePath& data_directory,
141 base::TaskRunner* task_runner) {
110 IDB_TRACE("IndexedDBFactory::GetDatabaseNames"); 142 IDB_TRACE("IndexedDBFactory::GetDatabaseNames");
111 // TODO(dgrogan): Plumb data_loss back to script eventually? 143 // TODO(dgrogan): Plumb data_loss back to script eventually?
112 blink::WebIDBDataLoss data_loss; 144 blink::WebIDBDataLoss data_loss;
113 std::string data_loss_message; 145 std::string data_loss_message;
114 bool disk_full; 146 bool disk_full;
115 scoped_refptr<IndexedDBBackingStore> backing_store = 147 scoped_refptr<IndexedDBBackingStore> backing_store =
116 OpenBackingStore(origin_url, 148 OpenBackingStore(origin_url,
117 data_directory, 149 data_directory,
150 NULL,
118 &data_loss, 151 &data_loss,
119 &data_loss_message, 152 &data_loss_message,
120 &disk_full); 153 &disk_full,
154 task_runner);
121 if (!backing_store) { 155 if (!backing_store) {
122 callbacks->OnError( 156 callbacks->OnError(
123 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 157 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError,
124 "Internal error opening backing store for " 158 "Internal error opening backing store for "
125 "indexedDB.webkitGetDatabaseNames.")); 159 "indexedDB.webkitGetDatabaseNames."));
126 return; 160 return;
127 } 161 }
128 162
129 callbacks->OnSuccess(backing_store->GetDatabaseNames()); 163 callbacks->OnSuccess(backing_store->GetDatabaseNames());
130 } 164 }
131 165
132 void IndexedDBFactory::DeleteDatabase( 166 void IndexedDBFactory::DeleteDatabase(
133 const string16& name, 167 const string16& name,
168 net::URLRequestContext* request_context,
134 scoped_refptr<IndexedDBCallbacks> callbacks, 169 scoped_refptr<IndexedDBCallbacks> callbacks,
135 const GURL& origin_url, 170 const GURL& origin_url,
136 const base::FilePath& data_directory) { 171 const base::FilePath& data_directory,
172 base::TaskRunner* task_runner) {
137 IDB_TRACE("IndexedDBFactory::DeleteDatabase"); 173 IDB_TRACE("IndexedDBFactory::DeleteDatabase");
138 IndexedDBDatabase::Identifier unique_identifier(origin_url, name); 174 IndexedDBDatabase::Identifier unique_identifier(origin_url, name);
139 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); 175 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier);
140 if (it != database_map_.end()) { 176 if (it != database_map_.end()) {
141 // If there are any connections to the database, directly delete the 177 // If there are any connections to the database, directly delete the
142 // database. 178 // database.
143 it->second->DeleteDatabase(callbacks); 179 it->second->DeleteDatabase(callbacks);
144 return; 180 return;
145 } 181 }
146 182
147 // TODO(dgrogan): Plumb data_loss back to script eventually? 183 // TODO(dgrogan): Plumb data_loss back to script eventually?
148 blink::WebIDBDataLoss data_loss; 184 blink::WebIDBDataLoss data_loss;
149 std::string data_loss_message; 185 std::string data_loss_message;
150 bool disk_full = false; 186 bool disk_full = false;
151 scoped_refptr<IndexedDBBackingStore> backing_store = 187 scoped_refptr<IndexedDBBackingStore> backing_store =
152 OpenBackingStore(origin_url, 188 OpenBackingStore(origin_url,
153 data_directory, 189 data_directory,
190 request_context,
154 &data_loss, 191 &data_loss,
155 &data_loss_message, 192 &data_loss_message,
156 &disk_full); 193 &disk_full,
194 task_runner);
157 if (!backing_store) { 195 if (!backing_store) {
158 callbacks->OnError( 196 callbacks->OnError(
159 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 197 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError,
160 ASCIIToUTF16( 198 ASCIIToUTF16(
161 "Internal error opening backing store " 199 "Internal error opening backing store "
162 "for indexedDB.deleteDatabase."))); 200 "for indexedDB.deleteDatabase.")));
163 return; 201 return;
164 } 202 }
165 203
166 scoped_refptr<IndexedDBDatabase> database = 204 scoped_refptr<IndexedDBDatabase> database =
(...skipping 17 matching lines...) Expand all
184 if (!context_) 222 if (!context_)
185 return; 223 return;
186 context_->ForceClose(origin_url); 224 context_->ForceClose(origin_url);
187 } 225 }
188 226
189 bool IndexedDBFactory::IsBackingStoreOpenForTesting(const GURL& origin_url) 227 bool IndexedDBFactory::IsBackingStoreOpenForTesting(const GURL& origin_url)
190 const { 228 const {
191 return backing_store_map_.find(origin_url) != backing_store_map_.end(); 229 return backing_store_map_.find(origin_url) != backing_store_map_.end();
192 } 230 }
193 231
232 scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStoreHelper(
233 const GURL& origin_url,
234 const base::FilePath& data_directory,
235 net::URLRequestContext* request_context,
236 blink::WebIDBDataLoss* data_loss,
237 std::string* data_loss_message,
238 bool* disk_full,
239 base::TaskRunner* task_runner,
240 bool first_time) {
241 return IndexedDBBackingStore::Open(this,
242 origin_url,
243 data_directory,
244 request_context,
245 data_loss,
246 data_loss_message,
247 disk_full,
248 task_runner,
249 first_time);
250 }
251
194 scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore( 252 scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore(
195 const GURL& origin_url, 253 const GURL& origin_url,
196 const base::FilePath& data_directory, 254 const base::FilePath& data_directory,
255 net::URLRequestContext* request_context,
197 blink::WebIDBDataLoss* data_loss, 256 blink::WebIDBDataLoss* data_loss,
198 std::string* data_loss_message, 257 std::string* data_loss_message,
199 bool* disk_full) { 258 bool* disk_full,
259 base::TaskRunner* task_runner) {
200 const bool open_in_memory = data_directory.empty(); 260 const bool open_in_memory = data_directory.empty();
201 261
202 IndexedDBBackingStoreMap::iterator it2 = backing_store_map_.find(origin_url); 262 IndexedDBBackingStoreMap::iterator it2 = backing_store_map_.find(origin_url);
203 if (it2 != backing_store_map_.end()) { 263 if (it2 != backing_store_map_.end()) {
204 it2->second->close_timer()->Stop(); 264 it2->second->close_timer()->Stop();
205 return it2->second; 265 return it2->second;
206 } 266 }
207 267
208 scoped_refptr<IndexedDBBackingStore> backing_store; 268 scoped_refptr<IndexedDBBackingStore> backing_store;
269 bool first_time = false;
209 if (open_in_memory) { 270 if (open_in_memory) {
210 backing_store = IndexedDBBackingStore::OpenInMemory(origin_url); 271 // TODO(ericu): Support blobs in in-memory backends.
272 backing_store =
273 IndexedDBBackingStore::OpenInMemory(origin_url, task_runner);
211 } else { 274 } else {
212 backing_store = IndexedDBBackingStore::Open(origin_url, 275 first_time = !backends_opened_since_boot_.count(origin_url);
213 data_directory, 276
214 data_loss, 277 backing_store = OpenBackingStoreHelper(origin_url,
215 data_loss_message, 278 data_directory,
216 disk_full); 279 request_context,
280 data_loss,
281 data_loss_message,
282 disk_full,
283 task_runner,
284 first_time);
217 } 285 }
218 286
219 if (backing_store.get()) { 287 if (backing_store.get()) {
288 if (first_time)
289 backends_opened_since_boot_.insert(origin_url);
220 backing_store_map_[origin_url] = backing_store; 290 backing_store_map_[origin_url] = backing_store;
221 // If an in-memory database, bind lifetime to this factory instance. 291 // If an in-memory database, bind lifetime to this factory instance.
222 if (open_in_memory) 292 if (open_in_memory)
223 session_only_backing_stores_.insert(backing_store); 293 session_only_backing_stores_.insert(backing_store);
224 294
225 // All backing stores associated with this factory should be of the same 295 // All backing stores associated with this factory should be of the same
226 // type. 296 // type.
227 DCHECK(session_only_backing_stores_.empty() || open_in_memory); 297 DCHECK(session_only_backing_stores_.empty() != open_in_memory);
228 298
229 return backing_store; 299 return backing_store;
230 } 300 }
231 301
232 return 0; 302 return 0;
233 } 303 }
234 304
235 void IndexedDBFactory::Open( 305 void IndexedDBFactory::Open(
236 const string16& name, 306 const string16& name,
237 int64 version, 307 int64 version,
308 net::URLRequestContext* request_context,
238 int64 transaction_id, 309 int64 transaction_id,
239 scoped_refptr<IndexedDBCallbacks> callbacks, 310 scoped_refptr<IndexedDBCallbacks> callbacks,
240 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, 311 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
241 const GURL& origin_url, 312 const GURL& origin_url,
242 const base::FilePath& data_directory) { 313 const base::FilePath& data_directory,
314 int child_process_id,
315 base::TaskRunner* task_runner) {
243 IDB_TRACE("IndexedDBFactory::Open"); 316 IDB_TRACE("IndexedDBFactory::Open");
244 scoped_refptr<IndexedDBDatabase> database; 317 scoped_refptr<IndexedDBDatabase> database;
245 IndexedDBDatabase::Identifier unique_identifier(origin_url, name); 318 IndexedDBDatabase::Identifier unique_identifier(origin_url, name);
246 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); 319 IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier);
247 blink::WebIDBDataLoss data_loss = 320 blink::WebIDBDataLoss data_loss =
248 blink::WebIDBDataLossNone; 321 blink::WebIDBDataLossNone;
249 std::string data_loss_message; 322 std::string data_loss_message;
250 bool disk_full = false; 323 bool disk_full = false;
251 if (it == database_map_.end()) { 324 if (it == database_map_.end()) {
252 scoped_refptr<IndexedDBBackingStore> backing_store = 325 scoped_refptr<IndexedDBBackingStore> backing_store =
253 OpenBackingStore(origin_url, 326 OpenBackingStore(origin_url,
254 data_directory, 327 data_directory,
328 request_context,
255 &data_loss, 329 &data_loss,
256 &data_loss_message, 330 &data_loss_message,
257 &disk_full); 331 &disk_full,
332 task_runner);
258 if (!backing_store) { 333 if (!backing_store) {
259 if (disk_full) { 334 if (disk_full) {
260 callbacks->OnError( 335 callbacks->OnError(
261 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError, 336 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError,
262 ASCIIToUTF16( 337 ASCIIToUTF16(
263 "Encountered full disk while opening " 338 "Encountered full disk while opening "
264 "backing store for indexedDB.open."))); 339 "backing store for indexedDB.open.")));
265 return; 340 return;
266 } 341 }
267 callbacks->OnError(IndexedDBDatabaseError( 342 callbacks->OnError(IndexedDBDatabaseError(
(...skipping 13 matching lines...) Expand all
281 return; 356 return;
282 } 357 }
283 358
284 database_map_[unique_identifier] = database; 359 database_map_[unique_identifier] = database;
285 } else { 360 } else {
286 database = it->second; 361 database = it->second;
287 } 362 }
288 363
289 database->OpenConnection(callbacks, 364 database->OpenConnection(callbacks,
290 database_callbacks, 365 database_callbacks,
366 child_process_id,
291 transaction_id, 367 transaction_id,
292 version, 368 version,
293 data_loss, 369 data_loss,
294 data_loss_message); 370 data_loss_message);
295 } 371 }
296 372
297 std::vector<IndexedDBDatabase*> IndexedDBFactory::GetOpenDatabasesForOrigin( 373 std::vector<IndexedDBDatabase*> IndexedDBFactory::GetOpenDatabasesForOrigin(
298 const GURL& origin_url) const { 374 const GURL& origin_url) const {
299 std::vector<IndexedDBDatabase*> result; 375 std::vector<IndexedDBDatabase*> result;
300 for (IndexedDBDatabaseMap::const_iterator it = database_map_.begin(); 376 for (IndexedDBDatabaseMap::const_iterator it = database_map_.begin();
301 it != database_map_.end(); 377 it != database_map_.end();
302 ++it) { 378 ++it) {
303 if (it->first.first == origin_url) 379 if (it->first.first == origin_url)
304 result.push_back(it->second.get()); 380 result.push_back(it->second.get());
305 } 381 }
306 return result; 382 return result;
307 } 383 }
308 384
309 } // namespace content 385 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698