Chromium Code Reviews| 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 // Preserve kMinimumPreserveForSystem disk space for system book-keeping | 66 // Preserve kMinimumPreserveForSystem disk space for system book-keeping |
| 67 // when returning the quota to unlimited apps/extensions. | 67 // when returning the quota to unlimited apps/extensions. |
| 68 // TODO(kinuko): This should be like 10% of the actual disk space. | 68 // TODO(kinuko): This should be like 10% of the actual disk space. |
| 69 // For now we simply use a constant as getting the disk size needs | 69 // For now we simply use a constant as getting the disk size needs |
| 70 // platform-dependent code. (http://crbug.com/178976) | 70 // platform-dependent code. (http://crbug.com/178976) |
| 71 int64 QuotaManager::kMinimumPreserveForSystem = 1024 * kMBytes; | 71 int64 QuotaManager::kMinimumPreserveForSystem = 1024 * kMBytes; |
| 72 | 72 |
| 73 const int QuotaManager::kEvictionIntervalInMilliSeconds = | 73 const int QuotaManager::kEvictionIntervalInMilliSeconds = |
| 74 30 * kMinutesInMilliSeconds; | 74 30 * kMinutesInMilliSeconds; |
| 75 | 75 |
| 76 const char QuotaManager::kTimeBetweenOriginEvictionsHistogram[] = | |
| 77 "Quota.TimeBetweenOriginEvictions"; | |
| 78 | |
| 76 // Heuristics: assuming average cloud server allows a few Gigs storage | 79 // Heuristics: assuming average cloud server allows a few Gigs storage |
| 77 // on the server side and the storage needs to be shared for user data | 80 // on the server side and the storage needs to be shared for user data |
| 78 // and by multiple apps. | 81 // and by multiple apps. |
| 79 int64 QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes; | 82 int64 QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes; |
| 80 | 83 |
| 81 namespace { | 84 namespace { |
| 82 | 85 |
| 83 void CountOriginType(const std::set<GURL>& origins, | 86 void CountOriginType(const std::set<GURL>& origins, |
| 84 SpecialStoragePolicy* policy, | 87 SpecialStoragePolicy* policy, |
| 85 size_t* protected_origins, | 88 size_t* protected_origins, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 SpecialStoragePolicy* policy, | 148 SpecialStoragePolicy* policy, |
| 146 GURL* url, | 149 GURL* url, |
| 147 QuotaDatabase* database) { | 150 QuotaDatabase* database) { |
| 148 DCHECK(database); | 151 DCHECK(database); |
| 149 database->GetLRUOrigin(type, *exceptions, policy, url); | 152 database->GetLRUOrigin(type, *exceptions, policy, url); |
| 150 return true; | 153 return true; |
| 151 } | 154 } |
| 152 | 155 |
| 153 bool DeleteOriginInfoOnDBThread(const GURL& origin, | 156 bool DeleteOriginInfoOnDBThread(const GURL& origin, |
| 154 StorageType type, | 157 StorageType type, |
| 158 bool is_eviction, | |
| 155 QuotaDatabase* database) { | 159 QuotaDatabase* database) { |
| 156 DCHECK(database); | 160 DCHECK(database); |
| 157 return database->DeleteOriginInfo(origin, type); | 161 if (!database->DeleteOriginInfo(origin, type)) |
| 162 return false; | |
| 163 | |
| 164 // If the deletion is not due to an eviction, delete the entry in the eviction | |
| 165 // table as well due to privacy concerns. | |
| 166 if (!is_eviction) | |
| 167 return database->DeleteOriginLastEvictionTime(origin, type); | |
| 168 | |
| 169 base::Time last_eviction_time; | |
| 170 if (!database->GetOriginLastEvictionTime(origin, type, &last_eviction_time)) | |
|
michaeln
2015/10/15 21:25:23
In looking at this closely now, I see there are tw
calamity
2015/10/16 00:53:04
Yeah, I agree. I think these are all great things
| |
| 171 return false; | |
| 172 | |
| 173 base::Time now = base::Time::Now(); | |
| 174 if (last_eviction_time != base::Time()) { | |
| 175 UMA_HISTOGRAM_LONG_TIMES(QuotaManager::kTimeBetweenOriginEvictionsHistogram, | |
|
michaeln
2015/10/15 21:25:23
To compute a failure rate (where failure is we rep
calamity
2015/10/16 00:53:04
Good point.
I think we have the total eviction co
| |
| 176 now - last_eviction_time); | |
| 177 } | |
| 178 | |
| 179 if (!database->SetOriginLastEvictionTime(origin, type, now)) | |
| 180 return false; | |
| 181 | |
| 182 return true; | |
| 158 } | 183 } |
| 159 | 184 |
| 160 bool InitializeTemporaryOriginsInfoOnDBThread(const std::set<GURL>* origins, | 185 bool InitializeTemporaryOriginsInfoOnDBThread(const std::set<GURL>* origins, |
| 161 QuotaDatabase* database) { | 186 QuotaDatabase* database) { |
| 162 DCHECK(database); | 187 DCHECK(database); |
| 163 if (database->IsOriginDatabaseBootstrapped()) | 188 if (database->IsOriginDatabaseBootstrapped()) |
| 164 return true; | 189 return true; |
| 165 | 190 |
| 166 // Register existing origins with 0 last time access. | 191 // Register existing origins with 0 last time access. |
| 167 if (database->RegisterInitialOriginInfo(*origins, kStorageTypeTemporary)) { | 192 if (database->RegisterInitialOriginInfo(*origins, kStorageTypeTemporary)) { |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 527 | 552 |
| 528 DISALLOW_COPY_AND_ASSIGN(GetUsageInfoTask); | 553 DISALLOW_COPY_AND_ASSIGN(GetUsageInfoTask); |
| 529 }; | 554 }; |
| 530 | 555 |
| 531 class QuotaManager::OriginDataDeleter : public QuotaTask { | 556 class QuotaManager::OriginDataDeleter : public QuotaTask { |
| 532 public: | 557 public: |
| 533 OriginDataDeleter(QuotaManager* manager, | 558 OriginDataDeleter(QuotaManager* manager, |
| 534 const GURL& origin, | 559 const GURL& origin, |
| 535 StorageType type, | 560 StorageType type, |
| 536 int quota_client_mask, | 561 int quota_client_mask, |
| 562 bool is_eviction, | |
| 537 const StatusCallback& callback) | 563 const StatusCallback& callback) |
| 538 : QuotaTask(manager), | 564 : QuotaTask(manager), |
| 539 origin_(origin), | 565 origin_(origin), |
| 540 type_(type), | 566 type_(type), |
| 541 quota_client_mask_(quota_client_mask), | 567 quota_client_mask_(quota_client_mask), |
| 542 error_count_(0), | 568 error_count_(0), |
| 543 remaining_clients_(-1), | 569 remaining_clients_(-1), |
| 544 skipped_clients_(0), | 570 skipped_clients_(0), |
| 571 is_eviction_(is_eviction), | |
| 545 callback_(callback), | 572 callback_(callback), |
| 546 weak_factory_(this) {} | 573 weak_factory_(this) {} |
| 547 | 574 |
| 548 protected: | 575 protected: |
| 549 void Run() override { | 576 void Run() override { |
| 550 error_count_ = 0; | 577 error_count_ = 0; |
| 551 remaining_clients_ = manager()->clients_.size(); | 578 remaining_clients_ = manager()->clients_.size(); |
| 552 for (QuotaClientList::iterator iter = manager()->clients_.begin(); | 579 for (QuotaClientList::iterator iter = manager()->clients_.begin(); |
| 553 iter != manager()->clients_.end(); ++iter) { | 580 iter != manager()->clients_.end(); ++iter) { |
| 554 if (quota_client_mask_ & (*iter)->id()) { | 581 if (quota_client_mask_ & (*iter)->id()) { |
| 555 (*iter)->DeleteOriginData( | 582 (*iter)->DeleteOriginData( |
| 556 origin_, type_, | 583 origin_, type_, |
| 557 base::Bind(&OriginDataDeleter::DidDeleteOriginData, | 584 base::Bind(&OriginDataDeleter::DidDeleteOriginData, |
| 558 weak_factory_.GetWeakPtr())); | 585 weak_factory_.GetWeakPtr())); |
| 559 } else { | 586 } else { |
| 560 ++skipped_clients_; | 587 ++skipped_clients_; |
| 561 if (--remaining_clients_ == 0) | 588 if (--remaining_clients_ == 0) |
| 562 CallCompleted(); | 589 CallCompleted(); |
| 563 } | 590 } |
| 564 } | 591 } |
| 565 } | 592 } |
| 566 | 593 |
| 567 void Completed() override { | 594 void Completed() override { |
| 568 if (error_count_ == 0) { | 595 if (error_count_ == 0) { |
| 569 // Only remove the entire origin if we didn't skip any client types. | 596 // Only remove the entire origin if we didn't skip any client types. |
| 570 if (skipped_clients_ == 0) | 597 if (skipped_clients_ == 0) |
| 571 manager()->DeleteOriginFromDatabase(origin_, type_); | 598 manager()->DeleteOriginFromDatabase(origin_, type_, is_eviction_); |
| 572 callback_.Run(kQuotaStatusOk); | 599 callback_.Run(kQuotaStatusOk); |
| 573 } else { | 600 } else { |
| 574 callback_.Run(kQuotaErrorInvalidModification); | 601 callback_.Run(kQuotaErrorInvalidModification); |
| 575 } | 602 } |
| 576 DeleteSoon(); | 603 DeleteSoon(); |
| 577 } | 604 } |
| 578 | 605 |
| 579 void Aborted() override { | 606 void Aborted() override { |
| 580 callback_.Run(kQuotaErrorAbort); | 607 callback_.Run(kQuotaErrorAbort); |
| 581 DeleteSoon(); | 608 DeleteSoon(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 595 QuotaManager* manager() const { | 622 QuotaManager* manager() const { |
| 596 return static_cast<QuotaManager*>(observer()); | 623 return static_cast<QuotaManager*>(observer()); |
| 597 } | 624 } |
| 598 | 625 |
| 599 GURL origin_; | 626 GURL origin_; |
| 600 StorageType type_; | 627 StorageType type_; |
| 601 int quota_client_mask_; | 628 int quota_client_mask_; |
| 602 int error_count_; | 629 int error_count_; |
| 603 int remaining_clients_; | 630 int remaining_clients_; |
| 604 int skipped_clients_; | 631 int skipped_clients_; |
| 632 bool is_eviction_; | |
| 605 StatusCallback callback_; | 633 StatusCallback callback_; |
| 606 | 634 |
| 607 base::WeakPtrFactory<OriginDataDeleter> weak_factory_; | 635 base::WeakPtrFactory<OriginDataDeleter> weak_factory_; |
| 608 DISALLOW_COPY_AND_ASSIGN(OriginDataDeleter); | 636 DISALLOW_COPY_AND_ASSIGN(OriginDataDeleter); |
| 609 }; | 637 }; |
| 610 | 638 |
| 611 class QuotaManager::HostDataDeleter : public QuotaTask { | 639 class QuotaManager::HostDataDeleter : public QuotaTask { |
| 612 public: | 640 public: |
| 613 HostDataDeleter(QuotaManager* manager, | 641 HostDataDeleter(QuotaManager* manager, |
| 614 const std::string& host, | 642 const std::string& host, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 664 else | 692 else |
| 665 CallCompleted(); | 693 CallCompleted(); |
| 666 } | 694 } |
| 667 } | 695 } |
| 668 | 696 |
| 669 void ScheduleOriginsDeletion() { | 697 void ScheduleOriginsDeletion() { |
| 670 remaining_deleters_ = origins_.size(); | 698 remaining_deleters_ = origins_.size(); |
| 671 for (std::set<GURL>::const_iterator p = origins_.begin(); | 699 for (std::set<GURL>::const_iterator p = origins_.begin(); |
| 672 p != origins_.end(); | 700 p != origins_.end(); |
| 673 ++p) { | 701 ++p) { |
| 674 OriginDataDeleter* deleter = | 702 OriginDataDeleter* deleter = new OriginDataDeleter( |
| 675 new OriginDataDeleter( | 703 manager(), *p, type_, quota_client_mask_, false, |
| 676 manager(), *p, type_, quota_client_mask_, | 704 base::Bind(&HostDataDeleter::DidDeleteOriginData, |
| 677 base::Bind(&HostDataDeleter::DidDeleteOriginData, | 705 weak_factory_.GetWeakPtr())); |
| 678 weak_factory_.GetWeakPtr())); | |
| 679 deleter->Start(); | 706 deleter->Start(); |
| 680 } | 707 } |
| 681 } | 708 } |
| 682 | 709 |
| 683 void DidDeleteOriginData(QuotaStatusCode status) { | 710 void DidDeleteOriginData(QuotaStatusCode status) { |
| 684 DCHECK_GT(remaining_deleters_, 0); | 711 DCHECK_GT(remaining_deleters_, 0); |
| 685 | 712 |
| 686 if (status != kQuotaStatusOk) | 713 if (status != kQuotaStatusOk) |
| 687 ++error_count_; | 714 ++error_count_; |
| 688 | 715 |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 918 | 945 |
| 919 void QuotaManager::SetUsageCacheEnabled(QuotaClient::ID client_id, | 946 void QuotaManager::SetUsageCacheEnabled(QuotaClient::ID client_id, |
| 920 const GURL& origin, | 947 const GURL& origin, |
| 921 StorageType type, | 948 StorageType type, |
| 922 bool enabled) { | 949 bool enabled) { |
| 923 LazyInitialize(); | 950 LazyInitialize(); |
| 924 DCHECK(GetUsageTracker(type)); | 951 DCHECK(GetUsageTracker(type)); |
| 925 GetUsageTracker(type)->SetUsageCacheEnabled(client_id, origin, enabled); | 952 GetUsageTracker(type)->SetUsageCacheEnabled(client_id, origin, enabled); |
| 926 } | 953 } |
| 927 | 954 |
| 928 void QuotaManager::DeleteOriginData( | 955 void QuotaManager::DeleteOriginData(const GURL& origin, |
| 929 const GURL& origin, StorageType type, int quota_client_mask, | 956 StorageType type, |
| 930 const StatusCallback& callback) { | 957 int quota_client_mask, |
| 931 LazyInitialize(); | 958 const StatusCallback& callback) { |
| 932 | 959 DeleteOriginDataInternal(origin, type, quota_client_mask, false, callback); |
| 933 if (origin.is_empty() || clients_.empty()) { | |
| 934 callback.Run(kQuotaStatusOk); | |
| 935 return; | |
| 936 } | |
| 937 | |
| 938 DCHECK(origin == origin.GetOrigin()); | |
| 939 OriginDataDeleter* deleter = | |
| 940 new OriginDataDeleter(this, origin, type, quota_client_mask, callback); | |
| 941 deleter->Start(); | |
| 942 } | 960 } |
| 943 | 961 |
| 944 void QuotaManager::DeleteHostData(const std::string& host, | 962 void QuotaManager::DeleteHostData(const std::string& host, |
| 945 StorageType type, | 963 StorageType type, |
| 946 int quota_client_mask, | 964 int quota_client_mask, |
| 947 const StatusCallback& callback) { | 965 const StatusCallback& callback) { |
| 948 LazyInitialize(); | 966 LazyInitialize(); |
| 949 | 967 |
| 950 if (host.empty() || clients_.empty()) { | 968 if (host.empty() || clients_.empty()) { |
| 951 callback.Run(kQuotaStatusOk); | 969 callback.Run(kQuotaStatusOk); |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1347 void QuotaManager::StartEviction() { | 1365 void QuotaManager::StartEviction() { |
| 1348 DCHECK(!temporary_storage_evictor_.get()); | 1366 DCHECK(!temporary_storage_evictor_.get()); |
| 1349 temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor( | 1367 temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor( |
| 1350 this, kEvictionIntervalInMilliSeconds)); | 1368 this, kEvictionIntervalInMilliSeconds)); |
| 1351 if (desired_available_space_ >= 0) | 1369 if (desired_available_space_ >= 0) |
| 1352 temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction( | 1370 temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction( |
| 1353 desired_available_space_); | 1371 desired_available_space_); |
| 1354 temporary_storage_evictor_->Start(); | 1372 temporary_storage_evictor_->Start(); |
| 1355 } | 1373 } |
| 1356 | 1374 |
| 1357 void QuotaManager::DeleteOriginFromDatabase( | 1375 void QuotaManager::DeleteOriginFromDatabase(const GURL& origin, |
| 1358 const GURL& origin, StorageType type) { | 1376 StorageType type, |
| 1377 bool is_eviction) { | |
| 1359 LazyInitialize(); | 1378 LazyInitialize(); |
| 1360 if (db_disabled_) | 1379 if (db_disabled_) |
| 1361 return; | 1380 return; |
| 1362 | 1381 |
| 1363 PostTaskAndReplyWithResultForDBThread( | 1382 PostTaskAndReplyWithResultForDBThread( |
| 1364 FROM_HERE, | 1383 FROM_HERE, |
| 1365 base::Bind(&DeleteOriginInfoOnDBThread, origin, type), | 1384 base::Bind(&DeleteOriginInfoOnDBThread, origin, type, is_eviction), |
| 1366 base::Bind(&QuotaManager::DidDatabaseWork, | 1385 base::Bind(&QuotaManager::DidDatabaseWork, weak_factory_.GetWeakPtr())); |
| 1367 weak_factory_.GetWeakPtr())); | |
| 1368 } | 1386 } |
| 1369 | 1387 |
| 1370 void QuotaManager::DidOriginDataEvicted(QuotaStatusCode status) { | 1388 void QuotaManager::DidOriginDataEvicted(QuotaStatusCode status) { |
| 1371 DCHECK(io_thread_->BelongsToCurrentThread()); | 1389 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 1372 | 1390 |
| 1373 // We only try evict origins that are not in use, so basically | 1391 // We only try evict origins that are not in use, so basically |
| 1374 // deletion attempt for eviction should not fail. Let's record | 1392 // deletion attempt for eviction should not fail. Let's record |
| 1375 // the origin if we get error and exclude it from future eviction | 1393 // the origin if we get error and exclude it from future eviction |
| 1376 // if the error happens consistently (> kThresholdOfErrorsToBeBlacklisted). | 1394 // if the error happens consistently (> kThresholdOfErrorsToBeBlacklisted). |
| 1377 if (status != kQuotaStatusOk) | 1395 if (status != kQuotaStatusOk) |
| 1378 origins_in_error_[eviction_context_.evicted_origin]++; | 1396 origins_in_error_[eviction_context_.evicted_origin]++; |
| 1379 | 1397 |
| 1380 eviction_context_.evict_origin_data_callback.Run(status); | 1398 eviction_context_.evict_origin_data_callback.Run(status); |
| 1381 eviction_context_.evict_origin_data_callback.Reset(); | 1399 eviction_context_.evict_origin_data_callback.Reset(); |
| 1382 } | 1400 } |
| 1383 | 1401 |
| 1402 void QuotaManager::DeleteOriginDataInternal(const GURL& origin, | |
| 1403 StorageType type, | |
| 1404 int quota_client_mask, | |
| 1405 bool is_eviction, | |
| 1406 const StatusCallback& callback) { | |
| 1407 LazyInitialize(); | |
| 1408 | |
| 1409 if (origin.is_empty() || clients_.empty()) { | |
| 1410 callback.Run(kQuotaStatusOk); | |
| 1411 return; | |
| 1412 } | |
| 1413 | |
| 1414 DCHECK(origin == origin.GetOrigin()); | |
| 1415 OriginDataDeleter* deleter = new OriginDataDeleter( | |
| 1416 this, origin, type, quota_client_mask, is_eviction, callback); | |
| 1417 deleter->Start(); | |
| 1418 } | |
| 1419 | |
| 1384 void QuotaManager::ReportHistogram() { | 1420 void QuotaManager::ReportHistogram() { |
| 1385 GetGlobalUsage(kStorageTypeTemporary, | 1421 GetGlobalUsage(kStorageTypeTemporary, |
| 1386 base::Bind( | 1422 base::Bind( |
| 1387 &QuotaManager::DidGetTemporaryGlobalUsageForHistogram, | 1423 &QuotaManager::DidGetTemporaryGlobalUsageForHistogram, |
| 1388 weak_factory_.GetWeakPtr())); | 1424 weak_factory_.GetWeakPtr())); |
| 1389 GetGlobalUsage(kStorageTypePersistent, | 1425 GetGlobalUsage(kStorageTypePersistent, |
| 1390 base::Bind( | 1426 base::Bind( |
| 1391 &QuotaManager::DidGetPersistentGlobalUsageForHistogram, | 1427 &QuotaManager::DidGetPersistentGlobalUsageForHistogram, |
| 1392 weak_factory_.GetWeakPtr())); | 1428 weak_factory_.GetWeakPtr())); |
| 1393 } | 1429 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1448 void QuotaManager::EvictOriginData(const GURL& origin, | 1484 void QuotaManager::EvictOriginData(const GURL& origin, |
| 1449 StorageType type, | 1485 StorageType type, |
| 1450 const EvictOriginDataCallback& callback) { | 1486 const EvictOriginDataCallback& callback) { |
| 1451 DCHECK(io_thread_->BelongsToCurrentThread()); | 1487 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 1452 DCHECK_EQ(type, kStorageTypeTemporary); | 1488 DCHECK_EQ(type, kStorageTypeTemporary); |
| 1453 | 1489 |
| 1454 eviction_context_.evicted_origin = origin; | 1490 eviction_context_.evicted_origin = origin; |
| 1455 eviction_context_.evicted_type = type; | 1491 eviction_context_.evicted_type = type; |
| 1456 eviction_context_.evict_origin_data_callback = callback; | 1492 eviction_context_.evict_origin_data_callback = callback; |
| 1457 | 1493 |
| 1458 DeleteOriginData(origin, type, QuotaClient::kAllClientsMask, | 1494 DeleteOriginDataInternal(origin, type, QuotaClient::kAllClientsMask, true, |
| 1459 base::Bind(&QuotaManager::DidOriginDataEvicted, | 1495 base::Bind(&QuotaManager::DidOriginDataEvicted, |
| 1460 weak_factory_.GetWeakPtr())); | 1496 weak_factory_.GetWeakPtr())); |
| 1461 } | 1497 } |
| 1462 | 1498 |
| 1463 void QuotaManager::GetUsageAndQuotaForEviction( | 1499 void QuotaManager::GetUsageAndQuotaForEviction( |
| 1464 const UsageAndQuotaCallback& callback) { | 1500 const UsageAndQuotaCallback& callback) { |
| 1465 DCHECK(io_thread_->BelongsToCurrentThread()); | 1501 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 1466 LazyInitialize(); | 1502 LazyInitialize(); |
| 1467 | 1503 |
| 1468 UsageAndQuotaCallbackDispatcher* dispatcher = | 1504 UsageAndQuotaCallbackDispatcher* dispatcher = |
| 1469 new UsageAndQuotaCallbackDispatcher(this); | 1505 new UsageAndQuotaCallbackDispatcher(this); |
| 1470 GetUsageTracker(kStorageTypeTemporary) | 1506 GetUsageTracker(kStorageTypeTemporary) |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1625 // |database_|, therefore we can be sure that database_ is alive when this | 1661 // |database_|, therefore we can be sure that database_ is alive when this |
| 1626 // task runs. | 1662 // task runs. |
| 1627 base::PostTaskAndReplyWithResult( | 1663 base::PostTaskAndReplyWithResult( |
| 1628 db_thread_.get(), | 1664 db_thread_.get(), |
| 1629 from_here, | 1665 from_here, |
| 1630 base::Bind(task, base::Unretained(database_.get())), | 1666 base::Bind(task, base::Unretained(database_.get())), |
| 1631 reply); | 1667 reply); |
| 1632 } | 1668 } |
| 1633 | 1669 |
| 1634 } // namespace storage | 1670 } // namespace storage |
| OLD | NEW |