Chromium Code Reviews| Index: net/http/broken_alternative_services.cc |
| diff --git a/net/http/broken_alternative_services.cc b/net/http/broken_alternative_services.cc |
| index ae7f7c4a2bd110ce35f11a10e3e03288aab1b853..33237adcaacbb6227454a7392f6b9f9b0421284f 100644 |
| --- a/net/http/broken_alternative_services.cc |
| +++ b/net/http/broken_alternative_services.cc |
| @@ -30,19 +30,24 @@ base::TimeDelta ComputeBrokenAlternativeServiceExpirationDelay( |
| } // namespace |
| -BrokenAlternativeServices::BrokenAlternativeServices(Delegate* delegate, |
| - base::TickClock* clock) |
| +BrokenAlternativeServices::BrokenAlternativeServices(Delegate* delegate) |
| : delegate_(delegate), |
| - clock_(clock), |
| + clock_(&default_clock_), |
| recently_broken_alternative_services_( |
| RecentlyBrokenAlternativeServices::NO_AUTO_EVICT), |
| weak_ptr_factory_(this) { |
| DCHECK(delegate_); |
| - DCHECK(clock_); |
| } |
| BrokenAlternativeServices::~BrokenAlternativeServices() {} |
| +void BrokenAlternativeServices::Clear() { |
| + expiration_timer_.Stop(); |
| + broken_alternative_service_list_.clear(); |
| + broken_alternative_service_map_.clear(); |
| + recently_broken_alternative_services_.Clear(); |
| +} |
| + |
| void BrokenAlternativeServices::MarkAlternativeServiceBroken( |
| const AlternativeService& alternative_service) { |
| // Empty host means use host of origin, callers are supposed to substitute. |
| @@ -69,7 +74,8 @@ void BrokenAlternativeServices::MarkAlternativeServiceBroken( |
| // If this is now the first entry in the list (i.e. |alternative_service| is |
| // the next alt svc to expire), schedule an expiration task for it. |
| if (list_it == broken_alternative_service_list_.begin()) { |
| - ScheduleBrokenAlternateProtocolMappingsExpiration(); |
| + ScheduleBrokenAlternateProtocolMappingsExpiration( |
| + broken_alternative_service_list_.front().second); |
| } |
| } |
| @@ -114,17 +120,12 @@ void BrokenAlternativeServices::ConfirmAlternativeService( |
| } |
| } |
| -const BrokenAlternativeServiceList& |
| -BrokenAlternativeServices::broken_alternative_service_list() const { |
| - return broken_alternative_service_list_; |
| +void BrokenAlternativeServices::SetTickClockForTesting(base::TickClock* clock) { |
| + DCHECK(clock); |
| + clock_ = clock; |
|
Ryan Hamilton
2017/06/12 18:57:32
I don't think I understand the clock-related chang
wangyix1
2017/06/14 00:01:25
Acknowledged. Will go back to clock being set usin
|
| } |
| -const RecentlyBrokenAlternativeServices& |
| -BrokenAlternativeServices::recently_broken_alternative_services() const { |
| - return recently_broken_alternative_services_; |
| -} |
| - |
| -bool BrokenAlternativeServices::AddBrokenAndRecentlyBrokenAlternativeServices( |
| +void BrokenAlternativeServices::AddBrokenAndRecentlyBrokenAlternativeServices( |
| std::unique_ptr<BrokenAlternativeServiceList> |
| broken_alternative_service_list, |
| std::unique_ptr<RecentlyBrokenAlternativeServices> |
| @@ -139,48 +140,49 @@ bool BrokenAlternativeServices::AddBrokenAndRecentlyBrokenAlternativeServices( |
| recently_broken_alternative_services->end()); |
| } |
| - bool added = false; |
| + base::TimeTicks next_expiration = |
| + broken_alternative_service_list_.empty() |
| + ? base::TimeTicks::Max() |
| + : broken_alternative_service_list_.front().second; |
| + |
| + // Add recently broken alt svcs to |recently_broken_alternative_services_|. |
| + // If an alt-svc already exists, update its broken-count to the one provided |
| + // in |recently_broken_alternative_services|. |
| recently_broken_alternative_services_.Swap( |
| *recently_broken_alternative_services); |
| // Add back all existing recently broken alt svcs to cache so they're at |
| - // front of recency list. |
| + // front of recency list (MRUCache::Get() does this automatically). |
| for (auto it = recently_broken_alternative_services->rbegin(); |
| it != recently_broken_alternative_services->rend(); ++it) { |
| if (recently_broken_alternative_services_.Get(it->first) == |
| recently_broken_alternative_services_.end()) { |
| recently_broken_alternative_services_.Put(it->first, it->second); |
| - added = true; |
| } |
| } |
| - // Add broken alt svcs to |broken_alternative_service_map_|. Remove all |
| - // that already exist in the map. |
| - auto it = broken_alternative_service_list->begin(); |
| - while (it != broken_alternative_service_list->end()) { |
| + // Add broken alt svcs to |broken_alternative_service_map_|. If an entry |
| + // already exists, delete its corresponding entry in |
| + // |broken_alternative_service_list_| and update its map entry to point to |
| + // its position in |broken_alternative_service_list|. |
| + for (auto it = broken_alternative_service_list->begin(); |
| + it != broken_alternative_service_list->end(); ++it) { |
| const AlternativeService& alternative_service = it->first; |
| - if (broken_alternative_service_map_.find(alternative_service) == |
| - broken_alternative_service_map_.end()) { |
| + auto map_it = broken_alternative_service_map_.find(alternative_service); |
| + if (map_it != broken_alternative_service_map_.end()) { |
| + broken_alternative_service_list_.erase(map_it->second); |
| + map_it->second = it; |
| + } else { |
| broken_alternative_service_map_.insert( |
| std::make_pair(alternative_service, it)); |
| - ++it; |
| - } else { |
| - broken_alternative_service_list->erase(it++); |
| } |
| } |
| - if (!broken_alternative_service_list->empty()) |
| - added = true; |
| - |
| // Merge |broken_alternative_service_list| with |
| // |broken_alternative_service_list_|. Both should already be sorted by |
| - // expiration time. |
| - bool schedule_expiration = |
| - (!broken_alternative_service_list->empty() && |
| - (broken_alternative_service_list_.empty() || |
| - broken_alternative_service_list->front().second < |
| - broken_alternative_service_list_.front().second)); |
| - |
| + // expiration time. std::list::merge() will not invalidate any iterators |
| + // of either list, so all iterators in |broken_alternative_service_map_| |
| + // remain valid. |
| broken_alternative_service_list_.merge( |
| *broken_alternative_service_list, |
| [](const std::pair<AlternativeService, base::TimeTicks>& lhs, |
| @@ -188,10 +190,23 @@ bool BrokenAlternativeServices::AddBrokenAndRecentlyBrokenAlternativeServices( |
| return lhs.second < rhs.second; |
| }); |
| - if (schedule_expiration) |
| - ScheduleBrokenAlternateProtocolMappingsExpiration(); |
| + base::TimeTicks new_next_expiration = |
| + broken_alternative_service_list_.empty() |
| + ? base::TimeTicks::Max() |
| + : broken_alternative_service_list_.front().second; |
| - return added; |
| + if (new_next_expiration != next_expiration) |
| + ScheduleBrokenAlternateProtocolMappingsExpiration(new_next_expiration); |
| +} |
| + |
| +const BrokenAlternativeServiceList& |
| +BrokenAlternativeServices::broken_alternative_service_list() const { |
| + return broken_alternative_service_list_; |
| +} |
| + |
| +const RecentlyBrokenAlternativeServices& |
| +BrokenAlternativeServices::recently_broken_alternative_services() const { |
| + return recently_broken_alternative_services_; |
| } |
| bool BrokenAlternativeServices::AddToBrokenAlternativeServiceListAndMap( |
| @@ -241,14 +256,14 @@ void BrokenAlternativeServices::ExpireBrokenAlternateProtocolMappings() { |
| } |
| if (!broken_alternative_service_list_.empty()) |
| - ScheduleBrokenAlternateProtocolMappingsExpiration(); |
| + ScheduleBrokenAlternateProtocolMappingsExpiration( |
| + broken_alternative_service_list_.front().second); |
| } |
| void BrokenAlternativeServices :: |
| - ScheduleBrokenAlternateProtocolMappingsExpiration() { |
| + ScheduleBrokenAlternateProtocolMappingsExpiration(base::TimeTicks when) { |
| DCHECK(!broken_alternative_service_list_.empty()); |
| base::TimeTicks now = clock_->NowTicks(); |
| - base::TimeTicks when = broken_alternative_service_list_.front().second; |
| base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
| expiration_timer_.Stop(); |
| expiration_timer_.Start( |