| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "storage/browser/quota/quota_manager.h" | 5 #include "storage/browser/quota/quota_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 // Preserve kMinimumPreserveForSystem disk space for system book-keeping | 67 // Preserve kMinimumPreserveForSystem disk space for system book-keeping |
| 68 // when returning the quota to unlimited apps/extensions. | 68 // when returning the quota to unlimited apps/extensions. |
| 69 // TODO(kinuko): This should be like 10% of the actual disk space. | 69 // TODO(kinuko): This should be like 10% of the actual disk space. |
| 70 // For now we simply use a constant as getting the disk size needs | 70 // For now we simply use a constant as getting the disk size needs |
| 71 // platform-dependent code. (http://crbug.com/178976) | 71 // platform-dependent code. (http://crbug.com/178976) |
| 72 int64 QuotaManager::kMinimumPreserveForSystem = 1024 * kMBytes; | 72 int64 QuotaManager::kMinimumPreserveForSystem = 1024 * kMBytes; |
| 73 | 73 |
| 74 const int QuotaManager::kEvictionIntervalInMilliSeconds = | 74 const int QuotaManager::kEvictionIntervalInMilliSeconds = |
| 75 30 * kMinutesInMilliSeconds; | 75 30 * kMinutesInMilliSeconds; |
| 76 | 76 |
| 77 const char QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram[] = |
| 78 "Quota.TimeBetweenRepeatedOriginEvictions"; |
| 79 |
| 77 // Heuristics: assuming average cloud server allows a few Gigs storage | 80 // Heuristics: assuming average cloud server allows a few Gigs storage |
| 78 // on the server side and the storage needs to be shared for user data | 81 // on the server side and the storage needs to be shared for user data |
| 79 // and by multiple apps. | 82 // and by multiple apps. |
| 80 int64 QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes; | 83 int64 QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes; |
| 81 | 84 |
| 82 namespace { | 85 namespace { |
| 83 | 86 |
| 84 void CountOriginType(const std::set<GURL>& origins, | 87 void CountOriginType(const std::set<GURL>& origins, |
| 85 SpecialStoragePolicy* policy, | 88 SpecialStoragePolicy* policy, |
| 86 size_t* protected_origins, | 89 size_t* protected_origins, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 SpecialStoragePolicy* policy, | 149 SpecialStoragePolicy* policy, |
| 147 GURL* url, | 150 GURL* url, |
| 148 QuotaDatabase* database) { | 151 QuotaDatabase* database) { |
| 149 DCHECK(database); | 152 DCHECK(database); |
| 150 database->GetLRUOrigin(type, *exceptions, policy, url); | 153 database->GetLRUOrigin(type, *exceptions, policy, url); |
| 151 return true; | 154 return true; |
| 152 } | 155 } |
| 153 | 156 |
| 154 bool DeleteOriginInfoOnDBThread(const GURL& origin, | 157 bool DeleteOriginInfoOnDBThread(const GURL& origin, |
| 155 StorageType type, | 158 StorageType type, |
| 159 bool is_eviction, |
| 156 QuotaDatabase* database) { | 160 QuotaDatabase* database) { |
| 157 DCHECK(database); | 161 DCHECK(database); |
| 158 return database->DeleteOriginInfo(origin, type); | 162 if (!database->DeleteOriginInfo(origin, type)) |
| 163 return false; |
| 164 |
| 165 // If the deletion is not due to an eviction, delete the entry in the eviction |
| 166 // table as well due to privacy concerns. |
| 167 if (!is_eviction) |
| 168 return database->DeleteOriginLastEvictionTime(origin, type); |
| 169 |
| 170 base::Time last_eviction_time; |
| 171 if (!database->GetOriginLastEvictionTime(origin, type, &last_eviction_time)) |
| 172 return false; |
| 173 |
| 174 base::Time now = base::Time::Now(); |
| 175 if (last_eviction_time != base::Time()) { |
| 176 UMA_HISTOGRAM_LONG_TIMES( |
| 177 QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram, |
| 178 now - last_eviction_time); |
| 179 } |
| 180 |
| 181 return database->SetOriginLastEvictionTime(origin, type, now); |
| 159 } | 182 } |
| 160 | 183 |
| 161 bool InitializeTemporaryOriginsInfoOnDBThread(const std::set<GURL>* origins, | 184 bool InitializeTemporaryOriginsInfoOnDBThread(const std::set<GURL>* origins, |
| 162 QuotaDatabase* database) { | 185 QuotaDatabase* database) { |
| 163 DCHECK(database); | 186 DCHECK(database); |
| 164 if (database->IsOriginDatabaseBootstrapped()) | 187 if (database->IsOriginDatabaseBootstrapped()) |
| 165 return true; | 188 return true; |
| 166 | 189 |
| 167 // Register existing origins with 0 last time access. | 190 // Register existing origins with 0 last time access. |
| 168 if (database->RegisterInitialOriginInfo(*origins, kStorageTypeTemporary)) { | 191 if (database->RegisterInitialOriginInfo(*origins, kStorageTypeTemporary)) { |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 | 567 |
| 545 DISALLOW_COPY_AND_ASSIGN(GetUsageInfoTask); | 568 DISALLOW_COPY_AND_ASSIGN(GetUsageInfoTask); |
| 546 }; | 569 }; |
| 547 | 570 |
| 548 class QuotaManager::OriginDataDeleter : public QuotaTask { | 571 class QuotaManager::OriginDataDeleter : public QuotaTask { |
| 549 public: | 572 public: |
| 550 OriginDataDeleter(QuotaManager* manager, | 573 OriginDataDeleter(QuotaManager* manager, |
| 551 const GURL& origin, | 574 const GURL& origin, |
| 552 StorageType type, | 575 StorageType type, |
| 553 int quota_client_mask, | 576 int quota_client_mask, |
| 577 bool is_eviction, |
| 554 const StatusCallback& callback) | 578 const StatusCallback& callback) |
| 555 : QuotaTask(manager), | 579 : QuotaTask(manager), |
| 556 origin_(origin), | 580 origin_(origin), |
| 557 type_(type), | 581 type_(type), |
| 558 quota_client_mask_(quota_client_mask), | 582 quota_client_mask_(quota_client_mask), |
| 559 error_count_(0), | 583 error_count_(0), |
| 560 remaining_clients_(-1), | 584 remaining_clients_(-1), |
| 561 skipped_clients_(0), | 585 skipped_clients_(0), |
| 586 is_eviction_(is_eviction), |
| 562 callback_(callback), | 587 callback_(callback), |
| 563 weak_factory_(this) {} | 588 weak_factory_(this) {} |
| 564 | 589 |
| 565 protected: | 590 protected: |
| 566 void Run() override { | 591 void Run() override { |
| 567 error_count_ = 0; | 592 error_count_ = 0; |
| 568 remaining_clients_ = manager()->clients_.size(); | 593 remaining_clients_ = manager()->clients_.size(); |
| 569 for (QuotaClientList::iterator iter = manager()->clients_.begin(); | 594 for (QuotaClientList::iterator iter = manager()->clients_.begin(); |
| 570 iter != manager()->clients_.end(); ++iter) { | 595 iter != manager()->clients_.end(); ++iter) { |
| 571 if (quota_client_mask_ & (*iter)->id()) { | 596 if (quota_client_mask_ & (*iter)->id()) { |
| 572 (*iter)->DeleteOriginData( | 597 (*iter)->DeleteOriginData( |
| 573 origin_, type_, | 598 origin_, type_, |
| 574 base::Bind(&OriginDataDeleter::DidDeleteOriginData, | 599 base::Bind(&OriginDataDeleter::DidDeleteOriginData, |
| 575 weak_factory_.GetWeakPtr())); | 600 weak_factory_.GetWeakPtr())); |
| 576 } else { | 601 } else { |
| 577 ++skipped_clients_; | 602 ++skipped_clients_; |
| 578 if (--remaining_clients_ == 0) | 603 if (--remaining_clients_ == 0) |
| 579 CallCompleted(); | 604 CallCompleted(); |
| 580 } | 605 } |
| 581 } | 606 } |
| 582 } | 607 } |
| 583 | 608 |
| 584 void Completed() override { | 609 void Completed() override { |
| 585 if (error_count_ == 0) { | 610 if (error_count_ == 0) { |
| 586 // crbug.com/349708 | 611 // crbug.com/349708 |
| 587 TRACE_EVENT0("io", "QuotaManager::OriginDataDeleter::Completed Ok"); | 612 TRACE_EVENT0("io", "QuotaManager::OriginDataDeleter::Completed Ok"); |
| 588 | 613 |
| 589 // Only remove the entire origin if we didn't skip any client types. | 614 // Only remove the entire origin if we didn't skip any client types. |
| 590 if (skipped_clients_ == 0) | 615 if (skipped_clients_ == 0) |
| 591 manager()->DeleteOriginFromDatabase(origin_, type_); | 616 manager()->DeleteOriginFromDatabase(origin_, type_, is_eviction_); |
| 592 callback_.Run(kQuotaStatusOk); | 617 callback_.Run(kQuotaStatusOk); |
| 593 } else { | 618 } else { |
| 594 // crbug.com/349708 | 619 // crbug.com/349708 |
| 595 TRACE_EVENT0("io", "QuotaManager::OriginDataDeleter::Completed Error"); | 620 TRACE_EVENT0("io", "QuotaManager::OriginDataDeleter::Completed Error"); |
| 596 | 621 |
| 597 callback_.Run(kQuotaErrorInvalidModification); | 622 callback_.Run(kQuotaErrorInvalidModification); |
| 598 } | 623 } |
| 599 DeleteSoon(); | 624 DeleteSoon(); |
| 600 } | 625 } |
| 601 | 626 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 618 QuotaManager* manager() const { | 643 QuotaManager* manager() const { |
| 619 return static_cast<QuotaManager*>(observer()); | 644 return static_cast<QuotaManager*>(observer()); |
| 620 } | 645 } |
| 621 | 646 |
| 622 GURL origin_; | 647 GURL origin_; |
| 623 StorageType type_; | 648 StorageType type_; |
| 624 int quota_client_mask_; | 649 int quota_client_mask_; |
| 625 int error_count_; | 650 int error_count_; |
| 626 int remaining_clients_; | 651 int remaining_clients_; |
| 627 int skipped_clients_; | 652 int skipped_clients_; |
| 653 bool is_eviction_; |
| 628 StatusCallback callback_; | 654 StatusCallback callback_; |
| 629 | 655 |
| 630 base::WeakPtrFactory<OriginDataDeleter> weak_factory_; | 656 base::WeakPtrFactory<OriginDataDeleter> weak_factory_; |
| 631 DISALLOW_COPY_AND_ASSIGN(OriginDataDeleter); | 657 DISALLOW_COPY_AND_ASSIGN(OriginDataDeleter); |
| 632 }; | 658 }; |
| 633 | 659 |
| 634 class QuotaManager::HostDataDeleter : public QuotaTask { | 660 class QuotaManager::HostDataDeleter : public QuotaTask { |
| 635 public: | 661 public: |
| 636 HostDataDeleter(QuotaManager* manager, | 662 HostDataDeleter(QuotaManager* manager, |
| 637 const std::string& host, | 663 const std::string& host, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 else | 719 else |
| 694 CallCompleted(); | 720 CallCompleted(); |
| 695 } | 721 } |
| 696 } | 722 } |
| 697 | 723 |
| 698 void ScheduleOriginsDeletion() { | 724 void ScheduleOriginsDeletion() { |
| 699 remaining_deleters_ = origins_.size(); | 725 remaining_deleters_ = origins_.size(); |
| 700 for (std::set<GURL>::const_iterator p = origins_.begin(); | 726 for (std::set<GURL>::const_iterator p = origins_.begin(); |
| 701 p != origins_.end(); | 727 p != origins_.end(); |
| 702 ++p) { | 728 ++p) { |
| 703 OriginDataDeleter* deleter = | 729 OriginDataDeleter* deleter = new OriginDataDeleter( |
| 704 new OriginDataDeleter( | 730 manager(), *p, type_, quota_client_mask_, false, |
| 705 manager(), *p, type_, quota_client_mask_, | 731 base::Bind(&HostDataDeleter::DidDeleteOriginData, |
| 706 base::Bind(&HostDataDeleter::DidDeleteOriginData, | 732 weak_factory_.GetWeakPtr())); |
| 707 weak_factory_.GetWeakPtr())); | |
| 708 deleter->Start(); | 733 deleter->Start(); |
| 709 } | 734 } |
| 710 } | 735 } |
| 711 | 736 |
| 712 void DidDeleteOriginData(QuotaStatusCode status) { | 737 void DidDeleteOriginData(QuotaStatusCode status) { |
| 713 DCHECK_GT(remaining_deleters_, 0); | 738 DCHECK_GT(remaining_deleters_, 0); |
| 714 | 739 |
| 715 if (status != kQuotaStatusOk) | 740 if (status != kQuotaStatusOk) |
| 716 ++error_count_; | 741 ++error_count_; |
| 717 | 742 |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 952 LazyInitialize(); | 977 LazyInitialize(); |
| 953 DCHECK(GetUsageTracker(type)); | 978 DCHECK(GetUsageTracker(type)); |
| 954 GetUsageTracker(type)->SetUsageCacheEnabled(client_id, origin, enabled); | 979 GetUsageTracker(type)->SetUsageCacheEnabled(client_id, origin, enabled); |
| 955 } | 980 } |
| 956 | 981 |
| 957 void QuotaManager::SetTemporaryStorageEvictionPolicy( | 982 void QuotaManager::SetTemporaryStorageEvictionPolicy( |
| 958 scoped_ptr<QuotaEvictionPolicy> policy) { | 983 scoped_ptr<QuotaEvictionPolicy> policy) { |
| 959 temporary_storage_eviction_policy_ = policy.Pass(); | 984 temporary_storage_eviction_policy_ = policy.Pass(); |
| 960 } | 985 } |
| 961 | 986 |
| 962 void QuotaManager::DeleteOriginData( | 987 void QuotaManager::DeleteOriginData(const GURL& origin, |
| 963 const GURL& origin, StorageType type, int quota_client_mask, | 988 StorageType type, |
| 964 const StatusCallback& callback) { | 989 int quota_client_mask, |
| 965 LazyInitialize(); | 990 const StatusCallback& callback) { |
| 966 | 991 DeleteOriginDataInternal(origin, type, quota_client_mask, false, callback); |
| 967 if (origin.is_empty() || clients_.empty()) { | |
| 968 callback.Run(kQuotaStatusOk); | |
| 969 return; | |
| 970 } | |
| 971 | |
| 972 DCHECK(origin == origin.GetOrigin()); | |
| 973 OriginDataDeleter* deleter = | |
| 974 new OriginDataDeleter(this, origin, type, quota_client_mask, callback); | |
| 975 deleter->Start(); | |
| 976 } | 992 } |
| 977 | 993 |
| 978 void QuotaManager::DeleteHostData(const std::string& host, | 994 void QuotaManager::DeleteHostData(const std::string& host, |
| 979 StorageType type, | 995 StorageType type, |
| 980 int quota_client_mask, | 996 int quota_client_mask, |
| 981 const StatusCallback& callback) { | 997 const StatusCallback& callback) { |
| 982 LazyInitialize(); | 998 LazyInitialize(); |
| 983 | 999 |
| 984 if (host.empty() || clients_.empty()) { | 1000 if (host.empty() || clients_.empty()) { |
| 985 callback.Run(kQuotaStatusOk); | 1001 callback.Run(kQuotaStatusOk); |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 void QuotaManager::StartEviction() { | 1399 void QuotaManager::StartEviction() { |
| 1384 DCHECK(!temporary_storage_evictor_.get()); | 1400 DCHECK(!temporary_storage_evictor_.get()); |
| 1385 temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor( | 1401 temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor( |
| 1386 this, kEvictionIntervalInMilliSeconds)); | 1402 this, kEvictionIntervalInMilliSeconds)); |
| 1387 if (desired_available_space_ >= 0) | 1403 if (desired_available_space_ >= 0) |
| 1388 temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction( | 1404 temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction( |
| 1389 desired_available_space_); | 1405 desired_available_space_); |
| 1390 temporary_storage_evictor_->Start(); | 1406 temporary_storage_evictor_->Start(); |
| 1391 } | 1407 } |
| 1392 | 1408 |
| 1393 void QuotaManager::DeleteOriginFromDatabase( | 1409 void QuotaManager::DeleteOriginFromDatabase(const GURL& origin, |
| 1394 const GURL& origin, StorageType type) { | 1410 StorageType type, |
| 1411 bool is_eviction) { |
| 1395 LazyInitialize(); | 1412 LazyInitialize(); |
| 1396 if (db_disabled_) | 1413 if (db_disabled_) |
| 1397 return; | 1414 return; |
| 1398 | 1415 |
| 1399 PostTaskAndReplyWithResultForDBThread( | 1416 PostTaskAndReplyWithResultForDBThread( |
| 1400 FROM_HERE, | 1417 FROM_HERE, |
| 1401 base::Bind(&DeleteOriginInfoOnDBThread, origin, type), | 1418 base::Bind(&DeleteOriginInfoOnDBThread, origin, type, is_eviction), |
| 1402 base::Bind(&QuotaManager::DidDatabaseWork, | 1419 base::Bind(&QuotaManager::DidDatabaseWork, weak_factory_.GetWeakPtr())); |
| 1403 weak_factory_.GetWeakPtr())); | |
| 1404 } | 1420 } |
| 1405 | 1421 |
| 1406 void QuotaManager::DidOriginDataEvicted(QuotaStatusCode status) { | 1422 void QuotaManager::DidOriginDataEvicted(QuotaStatusCode status) { |
| 1407 DCHECK(io_thread_->BelongsToCurrentThread()); | 1423 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 1408 | 1424 |
| 1409 // We only try evict origins that are not in use, so basically | 1425 // We only try evict origins that are not in use, so basically |
| 1410 // deletion attempt for eviction should not fail. Let's record | 1426 // deletion attempt for eviction should not fail. Let's record |
| 1411 // the origin if we get error and exclude it from future eviction | 1427 // the origin if we get error and exclude it from future eviction |
| 1412 // if the error happens consistently (> kThresholdOfErrorsToBeBlacklisted). | 1428 // if the error happens consistently (> kThresholdOfErrorsToBeBlacklisted). |
| 1413 if (status != kQuotaStatusOk) | 1429 if (status != kQuotaStatusOk) |
| 1414 origins_in_error_[eviction_context_.evicted_origin]++; | 1430 origins_in_error_[eviction_context_.evicted_origin]++; |
| 1415 | 1431 |
| 1416 eviction_context_.evict_origin_data_callback.Run(status); | 1432 eviction_context_.evict_origin_data_callback.Run(status); |
| 1417 eviction_context_.evict_origin_data_callback.Reset(); | 1433 eviction_context_.evict_origin_data_callback.Reset(); |
| 1418 } | 1434 } |
| 1419 | 1435 |
| 1436 void QuotaManager::DeleteOriginDataInternal(const GURL& origin, |
| 1437 StorageType type, |
| 1438 int quota_client_mask, |
| 1439 bool is_eviction, |
| 1440 const StatusCallback& callback) { |
| 1441 LazyInitialize(); |
| 1442 |
| 1443 if (origin.is_empty() || clients_.empty()) { |
| 1444 callback.Run(kQuotaStatusOk); |
| 1445 return; |
| 1446 } |
| 1447 |
| 1448 DCHECK(origin == origin.GetOrigin()); |
| 1449 OriginDataDeleter* deleter = new OriginDataDeleter( |
| 1450 this, origin, type, quota_client_mask, is_eviction, callback); |
| 1451 deleter->Start(); |
| 1452 } |
| 1453 |
| 1420 void QuotaManager::ReportHistogram() { | 1454 void QuotaManager::ReportHistogram() { |
| 1421 GetGlobalUsage(kStorageTypeTemporary, | 1455 GetGlobalUsage(kStorageTypeTemporary, |
| 1422 base::Bind( | 1456 base::Bind( |
| 1423 &QuotaManager::DidGetTemporaryGlobalUsageForHistogram, | 1457 &QuotaManager::DidGetTemporaryGlobalUsageForHistogram, |
| 1424 weak_factory_.GetWeakPtr())); | 1458 weak_factory_.GetWeakPtr())); |
| 1425 GetGlobalUsage(kStorageTypePersistent, | 1459 GetGlobalUsage(kStorageTypePersistent, |
| 1426 base::Bind( | 1460 base::Bind( |
| 1427 &QuotaManager::DidGetPersistentGlobalUsageForHistogram, | 1461 &QuotaManager::DidGetPersistentGlobalUsageForHistogram, |
| 1428 weak_factory_.GetWeakPtr())); | 1462 weak_factory_.GetWeakPtr())); |
| 1429 } | 1463 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 void QuotaManager::EvictOriginData(const GURL& origin, | 1548 void QuotaManager::EvictOriginData(const GURL& origin, |
| 1515 StorageType type, | 1549 StorageType type, |
| 1516 const EvictOriginDataCallback& callback) { | 1550 const EvictOriginDataCallback& callback) { |
| 1517 DCHECK(io_thread_->BelongsToCurrentThread()); | 1551 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 1518 DCHECK_EQ(type, kStorageTypeTemporary); | 1552 DCHECK_EQ(type, kStorageTypeTemporary); |
| 1519 | 1553 |
| 1520 eviction_context_.evicted_origin = origin; | 1554 eviction_context_.evicted_origin = origin; |
| 1521 eviction_context_.evicted_type = type; | 1555 eviction_context_.evicted_type = type; |
| 1522 eviction_context_.evict_origin_data_callback = callback; | 1556 eviction_context_.evict_origin_data_callback = callback; |
| 1523 | 1557 |
| 1524 DeleteOriginData(origin, type, QuotaClient::kAllClientsMask, | 1558 DeleteOriginDataInternal(origin, type, QuotaClient::kAllClientsMask, true, |
| 1525 base::Bind(&QuotaManager::DidOriginDataEvicted, | 1559 base::Bind(&QuotaManager::DidOriginDataEvicted, |
| 1526 weak_factory_.GetWeakPtr())); | 1560 weak_factory_.GetWeakPtr())); |
| 1527 } | 1561 } |
| 1528 | 1562 |
| 1529 void QuotaManager::GetUsageAndQuotaForEviction( | 1563 void QuotaManager::GetUsageAndQuotaForEviction( |
| 1530 const UsageAndQuotaCallback& callback) { | 1564 const UsageAndQuotaCallback& callback) { |
| 1531 // crbug.com/349708 | 1565 // crbug.com/349708 |
| 1532 TRACE_EVENT0("io", "QuotaManager::GetUsageAndQuotaForEviction"); | 1566 TRACE_EVENT0("io", "QuotaManager::GetUsageAndQuotaForEviction"); |
| 1533 | 1567 |
| 1534 DCHECK(io_thread_->BelongsToCurrentThread()); | 1568 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 1535 LazyInitialize(); | 1569 LazyInitialize(); |
| 1536 | 1570 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1699 // |database_|, therefore we can be sure that database_ is alive when this | 1733 // |database_|, therefore we can be sure that database_ is alive when this |
| 1700 // task runs. | 1734 // task runs. |
| 1701 base::PostTaskAndReplyWithResult( | 1735 base::PostTaskAndReplyWithResult( |
| 1702 db_thread_.get(), | 1736 db_thread_.get(), |
| 1703 from_here, | 1737 from_here, |
| 1704 base::Bind(task, base::Unretained(database_.get())), | 1738 base::Bind(task, base::Unretained(database_.get())), |
| 1705 reply); | 1739 reply); |
| 1706 } | 1740 } |
| 1707 | 1741 |
| 1708 } // namespace storage | 1742 } // namespace storage |
| OLD | NEW |