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

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

Issue 93873017: IndexedDBFactory now ForceCloses databases. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed memory leak Created 6 years, 11 months 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_context_impl.h" 5 #include "content/browser/indexed_db/indexed_db_context_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 info->SetDouble("last_modified", 180 info->SetDouble("last_modified",
181 GetOriginLastModified(origin_url).ToJsTime()); 181 GetOriginLastModified(origin_url).ToJsTime());
182 info->SetString("path", GetFilePath(origin_url).value()); 182 info->SetString("path", GetFilePath(origin_url).value());
183 info->SetDouble("connection_count", GetConnectionCount(origin_url)); 183 info->SetDouble("connection_count", GetConnectionCount(origin_url));
184 184
185 // This ends up being O(n^2) since we iterate over all open databases 185 // This ends up being O(n^2) since we iterate over all open databases
186 // to extract just those in the origin, and we're iterating over all 186 // to extract just those in the origin, and we're iterating over all
187 // origins in the outer loop. 187 // origins in the outer loop.
188 188
189 if (factory_) { 189 if (factory_) {
190 std::vector<IndexedDBDatabase*> databases = 190 std::pair<IndexedDBFactory::OriginDBMapIterator,
191 IndexedDBFactory::OriginDBMapIterator> range =
191 factory_->GetOpenDatabasesForOrigin(origin_url); 192 factory_->GetOpenDatabasesForOrigin(origin_url);
192 // TODO(jsbell): Sort by name? 193 // TODO(jsbell): Sort by name?
193 scoped_ptr<base::ListValue> database_list(new base::ListValue()); 194 scoped_ptr<base::ListValue> database_list(new base::ListValue());
194 195
195 for (std::vector<IndexedDBDatabase*>::iterator it = databases.begin(); 196 for (IndexedDBFactory::OriginDBMapIterator it = range.first;
196 it != databases.end(); 197 it != range.second;
197 ++it) { 198 ++it) {
198 199
199 const IndexedDBDatabase* db = *it; 200 const IndexedDBDatabase* db = it->second;
200 scoped_ptr<base::DictionaryValue> db_info(new base::DictionaryValue()); 201 scoped_ptr<base::DictionaryValue> db_info(new base::DictionaryValue());
201 202
202 db_info->SetString("name", db->name()); 203 db_info->SetString("name", db->name());
203 db_info->SetDouble("pending_opens", db->PendingOpenCount()); 204 db_info->SetDouble("pending_opens", db->PendingOpenCount());
204 db_info->SetDouble("pending_upgrades", db->PendingUpgradeCount()); 205 db_info->SetDouble("pending_upgrades", db->PendingUpgradeCount());
205 db_info->SetDouble("running_upgrades", db->RunningUpgradeCount()); 206 db_info->SetDouble("running_upgrades", db->RunningUpgradeCount());
206 db_info->SetDouble("pending_deletes", db->PendingDeleteCount()); 207 db_info->SetDouble("pending_deletes", db->PendingDeleteCount());
207 db_info->SetDouble("connection_count", 208 db_info->SetDouble("connection_count",
208 db->ConnectionCount() - db->PendingUpgradeCount() - 209 db->ConnectionCount() - db->PendingUpgradeCount() -
209 db->RunningUpgradeCount()); 210 db->RunningUpgradeCount());
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 origin_size_map_.erase(origin_url); 330 origin_size_map_.erase(origin_url);
330 space_available_map_.erase(origin_url); 331 space_available_map_.erase(origin_url);
331 } 332 }
332 } 333 }
333 334
334 void IndexedDBContextImpl::ForceClose(const GURL origin_url) { 335 void IndexedDBContextImpl::ForceClose(const GURL origin_url) {
335 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 336 DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
336 if (data_path_.empty() || !IsInOriginSet(origin_url)) 337 if (data_path_.empty() || !IsInOriginSet(origin_url))
337 return; 338 return;
338 339
339 if (connections_.find(origin_url) != connections_.end()) {
340 ConnectionSet& connections = connections_[origin_url];
341 ConnectionSet::iterator it = connections.begin();
342 while (it != connections.end()) {
343 // Remove before closing so callbacks don't double-erase
344 IndexedDBConnection* connection = *it;
345 DCHECK(connection->IsConnected());
346 connections.erase(it++);
347 connection->ForceClose();
348 }
349 DCHECK_EQ(connections_[origin_url].size(), 0UL);
350 connections_.erase(origin_url);
351 }
352 if (factory_) 340 if (factory_)
353 factory_->ForceClose(origin_url); 341 factory_->ForceClose(origin_url);
342 DCHECK_EQ(0UL, GetConnectionCount(origin_url));
354 } 343 }
355 344
356 size_t IndexedDBContextImpl::GetConnectionCount(const GURL& origin_url) { 345 size_t IndexedDBContextImpl::GetConnectionCount(const GURL& origin_url) {
357 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 346 DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
358 if (data_path_.empty() || !IsInOriginSet(origin_url)) 347 if (data_path_.empty() || !IsInOriginSet(origin_url))
359 return 0; 348 return 0;
360 349
361 if (connections_.find(origin_url) == connections_.end()) 350 if (!factory_)
362 return 0; 351 return 0;
363 352
364 return connections_[origin_url].size(); 353 return factory_->GetConnectionCount(origin_url);
365 } 354 }
366 355
367 base::FilePath IndexedDBContextImpl::GetFilePath(const GURL& origin_url) const { 356 base::FilePath IndexedDBContextImpl::GetFilePath(const GURL& origin_url) const {
368 std::string origin_id = webkit_database::GetIdentifierFromOrigin(origin_url); 357 std::string origin_id = webkit_database::GetIdentifierFromOrigin(origin_url);
369 return GetIndexedDBFilePath(origin_id); 358 return GetIndexedDBFilePath(origin_id);
370 } 359 }
371 360
372 base::FilePath IndexedDBContextImpl::GetFilePathForTesting( 361 base::FilePath IndexedDBContextImpl::GetFilePathForTesting(
373 const std::string& origin_id) const { 362 const std::string& origin_id) const {
374 return GetIndexedDBFilePath(origin_id); 363 return GetIndexedDBFilePath(origin_id);
375 } 364 }
376 365
377 void IndexedDBContextImpl::SetTaskRunnerForTesting( 366 void IndexedDBContextImpl::SetTaskRunnerForTesting(
378 base::SequencedTaskRunner* task_runner) { 367 base::SequencedTaskRunner* task_runner) {
379 DCHECK(!task_runner_); 368 DCHECK(!task_runner_);
380 task_runner_ = task_runner; 369 task_runner_ = task_runner;
381 } 370 }
382 371
383 void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url, 372 void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url,
384 IndexedDBConnection* connection) { 373 IndexedDBConnection* connection) {
385 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 374 DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
386 DCHECK_EQ(connections_[origin_url].count(connection), 0UL);
387 if (quota_manager_proxy()) { 375 if (quota_manager_proxy()) {
388 quota_manager_proxy()->NotifyStorageAccessed( 376 quota_manager_proxy()->NotifyStorageAccessed(
389 quota::QuotaClient::kIndexedDatabase, 377 quota::QuotaClient::kIndexedDatabase,
390 origin_url, 378 origin_url,
391 quota::kStorageTypeTemporary); 379 quota::kStorageTypeTemporary);
392 } 380 }
393 connections_[origin_url].insert(connection);
394 if (AddToOriginSet(origin_url)) { 381 if (AddToOriginSet(origin_url)) {
395 // A newly created db, notify the quota system. 382 // A newly created db, notify the quota system.
396 QueryDiskAndUpdateQuotaUsage(origin_url); 383 QueryDiskAndUpdateQuotaUsage(origin_url);
397 } else { 384 } else {
398 EnsureDiskUsageCacheInitialized(origin_url); 385 EnsureDiskUsageCacheInitialized(origin_url);
399 } 386 }
400 QueryAvailableQuota(origin_url); 387 QueryAvailableQuota(origin_url);
401 } 388 }
402 389
403 void IndexedDBContextImpl::ConnectionClosed(const GURL& origin_url, 390 void IndexedDBContextImpl::ConnectionClosed(const GURL& origin_url,
404 IndexedDBConnection* connection) { 391 IndexedDBConnection* connection) {
405 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 392 DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
406 // May not be in the map if connection was forced to close
407 if (connections_.find(origin_url) == connections_.end() ||
408 connections_[origin_url].count(connection) != 1)
409 return;
410 if (quota_manager_proxy()) { 393 if (quota_manager_proxy()) {
411 quota_manager_proxy()->NotifyStorageAccessed( 394 quota_manager_proxy()->NotifyStorageAccessed(
412 quota::QuotaClient::kIndexedDatabase, 395 quota::QuotaClient::kIndexedDatabase,
413 origin_url, 396 origin_url,
414 quota::kStorageTypeTemporary); 397 quota::kStorageTypeTemporary);
415 } 398 }
416 connections_[origin_url].erase(connection); 399 if (factory_ && factory_->GetConnectionCount(origin_url) == 0)
417 if (connections_[origin_url].size() == 0) {
418 QueryDiskAndUpdateQuotaUsage(origin_url); 400 QueryDiskAndUpdateQuotaUsage(origin_url);
419 connections_.erase(origin_url);
420 }
421 } 401 }
422 402
423 void IndexedDBContextImpl::TransactionComplete(const GURL& origin_url) { 403 void IndexedDBContextImpl::TransactionComplete(const GURL& origin_url) {
424 DCHECK(connections_.find(origin_url) != connections_.end() && 404 DCHECK(!factory_ || factory_->GetConnectionCount(origin_url) > 0);
425 connections_[origin_url].size() > 0);
426 QueryDiskAndUpdateQuotaUsage(origin_url); 405 QueryDiskAndUpdateQuotaUsage(origin_url);
427 QueryAvailableQuota(origin_url); 406 QueryAvailableQuota(origin_url);
428 } 407 }
429 408
430 void IndexedDBContextImpl::DatabaseDeleted(const GURL& origin_url) { 409 void IndexedDBContextImpl::DatabaseDeleted(const GURL& origin_url) {
431 AddToOriginSet(origin_url); 410 AddToOriginSet(origin_url);
432 QueryDiskAndUpdateQuotaUsage(origin_url); 411 QueryDiskAndUpdateQuotaUsage(origin_url);
433 QueryAvailableQuota(origin_url); 412 QueryAvailableQuota(origin_url);
434 } 413 }
435 414
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 origin_set_.reset(); 561 origin_set_.reset();
583 origin_size_map_.clear(); 562 origin_size_map_.clear();
584 space_available_map_.clear(); 563 space_available_map_.clear();
585 } 564 }
586 565
587 base::TaskRunner* IndexedDBContextImpl::TaskRunner() const { 566 base::TaskRunner* IndexedDBContextImpl::TaskRunner() const {
588 return task_runner_; 567 return task_runner_;
589 } 568 }
590 569
591 } // namespace content 570 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_context_impl.h ('k') | content/browser/indexed_db/indexed_db_database.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698