Index: content/browser/indexed_db/indexed_db_factory.cc |
diff --git a/content/browser/indexed_db/indexed_db_factory.cc b/content/browser/indexed_db/indexed_db_factory.cc |
index 2cfef62c90643e6c8f75bf98910b10bc9a0d21f3..69a9c062a596ed2e7ee21dfecc2c60180050ac57 100644 |
--- a/content/browser/indexed_db/indexed_db_factory.cc |
+++ b/content/browser/indexed_db/indexed_db_factory.cc |
@@ -40,6 +40,15 @@ void IndexedDBFactory::ReleaseDatabase( |
void IndexedDBFactory::ReleaseBackingStore(const GURL& origin_url, |
bool immediate) { |
+ if (immediate) { |
+ IndexedDBBackingStoreMap::iterator it = |
+ backing_stores_with_active_blobs_.find(origin_url); |
+ if (it != backing_stores_with_active_blobs_.end()) { |
+ it->second->active_blob_registry()->ForceShutdown(); |
+ backing_stores_with_active_blobs_.erase(it); |
+ } |
+ } |
+ |
// Only close if this is the last reference. |
if (!HasLastBackingStoreReference(origin_url)) |
return; |
@@ -100,13 +109,36 @@ void IndexedDBFactory::ContextDestroyed() { |
++it) |
it->second->close_timer()->Stop(); |
backing_store_map_.clear(); |
+ backing_stores_with_active_blobs_.clear(); |
context_ = NULL; |
} |
+void IndexedDBFactory::ReportOutstandingBlobs( |
+ const GURL& origin_url, bool blobs_outstanding) { |
+ if (!context_) |
+ return; |
+ if (blobs_outstanding) { |
+ DCHECK(!backing_stores_with_active_blobs_.count(origin_url)); |
+ IndexedDBBackingStoreMap::iterator it = backing_store_map_.find(origin_url); |
+ if (it != backing_store_map_.end()) |
+ backing_stores_with_active_blobs_.insert(*it); |
+ else |
+ DCHECK(false); |
+ } else { |
+ IndexedDBBackingStoreMap::iterator it = |
+ backing_stores_with_active_blobs_.find(origin_url); |
+ if (it != backing_stores_with_active_blobs_.end()) { |
+ backing_stores_with_active_blobs_.erase(it); |
+ ReleaseBackingStore(origin_url, false); |
+ } |
+ } |
+} |
+ |
void IndexedDBFactory::GetDatabaseNames( |
scoped_refptr<IndexedDBCallbacks> callbacks, |
const GURL& origin_url, |
- const base::FilePath& data_directory) { |
+ const base::FilePath& data_directory, |
+ base::TaskRunner* task_runner) { |
IDB_TRACE("IndexedDBFactory::GetDatabaseNames"); |
// TODO(dgrogan): Plumb data_loss back to script eventually? |
blink::WebIDBDataLoss data_loss; |
@@ -115,9 +147,11 @@ void IndexedDBFactory::GetDatabaseNames( |
scoped_refptr<IndexedDBBackingStore> backing_store = |
OpenBackingStore(origin_url, |
data_directory, |
+ NULL, |
&data_loss, |
&data_loss_message, |
- &disk_full); |
+ &disk_full, |
+ task_runner); |
if (!backing_store) { |
callbacks->OnError( |
IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
@@ -131,9 +165,11 @@ void IndexedDBFactory::GetDatabaseNames( |
void IndexedDBFactory::DeleteDatabase( |
const string16& name, |
+ net::URLRequestContext* request_context, |
scoped_refptr<IndexedDBCallbacks> callbacks, |
const GURL& origin_url, |
- const base::FilePath& data_directory) { |
+ const base::FilePath& data_directory, |
+ base::TaskRunner* task_runner) { |
IDB_TRACE("IndexedDBFactory::DeleteDatabase"); |
IndexedDBDatabase::Identifier unique_identifier(origin_url, name); |
IndexedDBDatabaseMap::iterator it = database_map_.find(unique_identifier); |
@@ -151,9 +187,11 @@ void IndexedDBFactory::DeleteDatabase( |
scoped_refptr<IndexedDBBackingStore> backing_store = |
OpenBackingStore(origin_url, |
data_directory, |
+ request_context, |
&data_loss, |
&data_loss_message, |
- &disk_full); |
+ &disk_full, |
+ task_runner); |
if (!backing_store) { |
callbacks->OnError( |
IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
@@ -191,12 +229,34 @@ bool IndexedDBFactory::IsBackingStoreOpenForTesting(const GURL& origin_url) |
return backing_store_map_.find(origin_url) != backing_store_map_.end(); |
} |
+scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStoreHelper( |
+ const GURL& origin_url, |
+ const base::FilePath& data_directory, |
+ net::URLRequestContext* request_context, |
+ blink::WebIDBDataLoss* data_loss, |
+ std::string* data_loss_message, |
+ bool* disk_full, |
+ base::TaskRunner* task_runner, |
+ bool first_time) { |
+ return IndexedDBBackingStore::Open(this, |
+ origin_url, |
+ data_directory, |
+ request_context, |
+ data_loss, |
+ data_loss_message, |
+ disk_full, |
+ task_runner, |
+ first_time); |
+} |
+ |
scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore( |
const GURL& origin_url, |
const base::FilePath& data_directory, |
+ net::URLRequestContext* request_context, |
blink::WebIDBDataLoss* data_loss, |
std::string* data_loss_message, |
- bool* disk_full) { |
+ bool* disk_full, |
+ base::TaskRunner* task_runner) { |
const bool open_in_memory = data_directory.empty(); |
IndexedDBBackingStoreMap::iterator it2 = backing_store_map_.find(origin_url); |
@@ -206,17 +266,27 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore( |
} |
scoped_refptr<IndexedDBBackingStore> backing_store; |
+ bool first_time = false; |
if (open_in_memory) { |
- backing_store = IndexedDBBackingStore::OpenInMemory(origin_url); |
+ // TODO(ericu): Support blobs in in-memory backends. |
+ backing_store = IndexedDBBackingStore::OpenInMemory(origin_url, |
+ task_runner); |
} else { |
- backing_store = IndexedDBBackingStore::Open(origin_url, |
- data_directory, |
- data_loss, |
- data_loss_message, |
- disk_full); |
+ first_time = !backends_opened_since_boot_.count(origin_url); |
+ |
+ backing_store = OpenBackingStoreHelper(origin_url, |
+ data_directory, |
+ request_context, |
+ data_loss, |
+ data_loss_message, |
+ disk_full, |
+ task_runner, |
+ first_time); |
} |
if (backing_store.get()) { |
+ if (first_time) |
+ backends_opened_since_boot_.insert(origin_url); |
backing_store_map_[origin_url] = backing_store; |
// If an in-memory database, bind lifetime to this factory instance. |
if (open_in_memory) |
@@ -224,7 +294,7 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore( |
// All backing stores associated with this factory should be of the same |
// type. |
- DCHECK(session_only_backing_stores_.empty() || open_in_memory); |
+ DCHECK(session_only_backing_stores_.empty() != open_in_memory); |
return backing_store; |
} |
@@ -235,11 +305,14 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBFactory::OpenBackingStore( |
void IndexedDBFactory::Open( |
const string16& name, |
int64 version, |
+ net::URLRequestContext* request_context, |
int64 transaction_id, |
scoped_refptr<IndexedDBCallbacks> callbacks, |
scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, |
const GURL& origin_url, |
- const base::FilePath& data_directory) { |
+ const base::FilePath& data_directory, |
+ int child_process_id, |
+ base::TaskRunner* task_runner) { |
IDB_TRACE("IndexedDBFactory::Open"); |
scoped_refptr<IndexedDBDatabase> database; |
IndexedDBDatabase::Identifier unique_identifier(origin_url, name); |
@@ -252,9 +325,11 @@ void IndexedDBFactory::Open( |
scoped_refptr<IndexedDBBackingStore> backing_store = |
OpenBackingStore(origin_url, |
data_directory, |
+ request_context, |
&data_loss, |
&data_loss_message, |
- &disk_full); |
+ &disk_full, |
+ task_runner); |
if (!backing_store) { |
if (disk_full) { |
callbacks->OnError( |
@@ -288,6 +363,7 @@ void IndexedDBFactory::Open( |
database->OpenConnection(callbacks, |
database_callbacks, |
+ child_process_id, |
transaction_id, |
version, |
data_loss, |