Chromium Code Reviews| 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( |