Index: content/browser/in_process_webkit/indexed_db_dispatcher_host.cc |
diff --git a/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc b/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc |
index 16ca3a7781e50943c23d8640cff2e737cb9a4e1a..dc914368ef65a89c4c5a1703b9b67176443f3c7a 100644 |
--- a/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc |
+++ b/content/browser/in_process_webkit/indexed_db_dispatcher_host.cc |
@@ -155,7 +155,7 @@ int32 IndexedDBDispatcherHost::Add(WebIDBDatabase* idb_database, |
return 0; |
} |
int32 idb_database_id = database_dispatcher_host_->map_.Add(idb_database); |
- database_dispatcher_host_->url_map_[idb_database_id] = origin_url; |
+ database_dispatcher_host_->database_url_map_[idb_database_id] = origin_url; |
return idb_database_id; |
} |
@@ -179,18 +179,21 @@ int32 IndexedDBDispatcherHost::Add(WebIDBObjectStore* idb_object_store) { |
return object_store_dispatcher_host_->map_.Add(idb_object_store); |
} |
-int32 IndexedDBDispatcherHost::Add(WebIDBTransaction* idb_transaction) { |
+int32 IndexedDBDispatcherHost::Add(WebIDBTransaction* idb_transaction, |
+ const GURL& url) { |
if (!transaction_dispatcher_host_.get()) { |
delete idb_transaction; |
return 0; |
} |
int32 id = transaction_dispatcher_host_->map_.Add(idb_transaction); |
idb_transaction->setCallbacks(new IndexedDBTransactionCallbacks(this, id)); |
+ transaction_dispatcher_host_->transaction_url_map_[id] = url; |
return id; |
} |
void IndexedDBDispatcherHost::OnIDBFactoryOpen( |
const IndexedDBHostMsg_FactoryOpen_Params& params) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)); |
FilePath base_path = webkit_context_->data_path(); |
FilePath indexed_db_path; |
if (!base_path.empty()) { |
@@ -255,6 +258,18 @@ void IndexedDBDispatcherHost::OnIDBFactoryDeleteDatabase( |
webkit_glue::FilePathToWebString(indexed_db_path)); |
} |
+void IndexedDBDispatcherHost::TransactionComplete(int32 transaction_id) { |
+ int bytes_used = |
+ transaction_dispatcher_host_->transaction_size_map_[transaction_id]; |
+ if (bytes_used) |
+ Context()->quota_manager_proxy()->NotifyStorageModified( |
+ quota::QuotaClient::kIndexedDatabase, |
+ transaction_dispatcher_host_->transaction_url_map_[transaction_id], |
+ quota::kStorageTypeTemporary, |
+ bytes_used); |
+ transaction_dispatcher_host_->transaction_size_map_.erase(transaction_id); |
+} |
+ |
////////////////////////////////////////////////////////////////////// |
// Helper templates. |
// |
@@ -404,7 +419,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnSetVersion( |
*ec = 0; |
idb_database->setVersion( |
version, |
- new IndexedDBCallbacks<WebIDBTransaction>(parent_, response_id), |
+ new IndexedDBCallbacks<WebIDBTransaction>(parent_, response_id, |
+ database_url_map_[idb_database_id]), |
*ec); |
} |
@@ -430,7 +446,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnTransaction( |
WebIDBTransaction* transaction = database->transaction( |
object_stores, mode, timeout, *ec); |
DCHECK(!transaction != !*ec); |
- *idb_transaction_id = *ec ? 0 : parent_->Add(transaction); |
+ *idb_transaction_id = |
+ *ec ? 0 : parent_->Add(transaction, database_url_map_[idb_database_id]); |
} |
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnOpen( |
@@ -446,9 +463,9 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnClose( |
&map_, idb_database_id); |
database->close(); |
parent_->Context()->quota_manager_proxy()->NotifyStorageAccessed( |
- quota::QuotaClient::kIndexedDatabase, url_map_[idb_database_id], |
+ quota::QuotaClient::kIndexedDatabase, database_url_map_[idb_database_id], |
quota::kStorageTypeTemporary); |
- url_map_.erase(idb_database_id); |
+ database_url_map_.erase(idb_database_id); |
} |
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDestroyed( |
@@ -688,6 +705,53 @@ void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnGet( |
idb_object_store->get(key, callbacks.release(), *idb_transaction, *ec); |
} |
+static void AbortTransaction(WebIDBTransaction* idb_transaction) { |
+ idb_transaction->abort(); |
michaeln
2011/07/27 01:31:35
could idb_transaction have been deleted prior to t
|
+} |
+ |
+static void DidCompleteTaskEvents(WebIDBTransaction* idb_transaction) { |
+ idb_transaction->didCompleteTaskEvents(); |
+} |
+ |
+class IndexedDBGetUsageAndQuotaCallback : |
+ public quota::QuotaManager::GetUsageAndQuotaCallback { |
+ public: |
+ IndexedDBGetUsageAndQuotaCallback(int64 size, |
+ WebIDBTransaction* idb_transaction) |
+ : size_(size), |
+ idb_transaction_(idb_transaction) { |
michaeln
2011/07/27 01:31:35
nit: indent is off
|
+ } |
+ |
+ void Run(quota::QuotaStatusCode status, int64 usage, int64 quota) { |
+ if (size_ > (quota - usage)) { |
+ BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, |
+ NewRunnableFunction(&AbortTransaction, idb_transaction_)); |
+ } else { |
+ BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE, |
+ NewRunnableFunction(&DidCompleteTaskEvents, idb_transaction_)); |
+ } |
+ } |
+ |
+ virtual void RunWithParams( |
+ const Tuple3<quota::QuotaStatusCode, int64, int64>& params) { |
+ Run(params.a, params.b, params.c); |
+ } |
+ |
+ private: |
+ int64 size_; |
+ WebIDBTransaction* idb_transaction_; |
+}; |
+ |
+static void RequestQuota( |
+ scoped_refptr<quota::QuotaManagerProxy> proxy, const GURL& gurl, |
+ IndexedDBGetUsageAndQuotaCallback* idb_quota_callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ proxy->quota_manager()->GetUsageAndQuota( |
+ gurl, |
+ quota::kStorageTypeTemporary, |
+ idb_quota_callback); |
+} |
+ |
void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnPut( |
const IndexedDBHostMsg_ObjectStorePut_Params& params, |
WebKit::WebExceptionCode* ec) { |
@@ -702,8 +766,17 @@ void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnPut( |
*ec = 0; |
scoped_ptr<WebIDBCallbacks> callbacks( |
new IndexedDBCallbacks<WebIDBKey>(parent_, params.response_id)); |
+ |
idb_object_store->put(params.serialized_value, params.key, params.put_mode, |
callbacks.release(), *idb_transaction, *ec); |
+ if (*ec) |
+ return; |
+ // TODO(dgrogan): Count key size too. |
+ // TODO(dgrogan): Figure out how accurate this is in terms of disk space used. |
michaeln
2011/07/27 01:31:35
Eavesdropping on OnPut/OnDelete/OnClear/OnIndex/On
dgrogan
2011/07/27 22:56:01
Your concerns are valid. The issue is that LevelD
dgrogan
2011/07/29 18:14:04
So, I realized that's not how the quota manager wo
|
+ int64 size = UTF16ToUTF8(params.serialized_value.data()).size(); |
+ WebIDBTransactionIDToSizeMap* map = |
+ &parent_->transaction_dispatcher_host_->transaction_size_map_; |
+ (*map)[params.transaction_id] += size; |
} |
void IndexedDBDispatcherHost::ObjectStoreDispatcherHost::OnDelete( |
@@ -1033,7 +1106,22 @@ void IndexedDBDispatcherHost:: |
if (!idb_transaction) |
return; |
- idb_transaction->didCompleteTaskEvents(); |
+ if (transaction_size_map_.find(transaction_id) == |
+ transaction_size_map_.end()) { |
michaeln
2011/07/27 01:31:35
i see... no Puts(), so no size map entry, so nothi
|
+ idb_transaction->didCompleteTaskEvents(); |
+ return; |
+ } |
+ // Check if there is available quota. |
+ IndexedDBGetUsageAndQuotaCallback* callback = |
+ new IndexedDBGetUsageAndQuotaCallback( |
+ transaction_size_map_[transaction_id], idb_transaction); |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ NewRunnableFunction(&RequestQuota, |
+ scoped_refptr<quota::QuotaManagerProxy>( |
+ parent_->Context()->quota_manager_proxy()), |
+ transaction_url_map_[transaction_id], |
+ callback)); |
+ |
} |
void IndexedDBDispatcherHost::TransactionDispatcherHost::OnDestroyed( |