OLD | NEW |
---|---|
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2017 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 "net/http/broken_alternative_services.h" | 5 #include "net/http/broken_alternative_services.h" |
6 | 6 |
7 #include "base/memory/singleton.h" | 7 #include "base/memory/singleton.h" |
8 #include "base/time/tick_clock.h" | 8 #include "base/time/tick_clock.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "net/http/http_server_properties_impl.h" | 10 #include "net/http/http_server_properties_impl.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 broken_alternative_service_list_.erase(map_it->second); | 107 broken_alternative_service_list_.erase(map_it->second); |
108 broken_alternative_service_map_.erase(map_it); | 108 broken_alternative_service_map_.erase(map_it); |
109 } | 109 } |
110 | 110 |
111 auto it = recently_broken_alternative_services_.Get(alternative_service); | 111 auto it = recently_broken_alternative_services_.Get(alternative_service); |
112 if (it != recently_broken_alternative_services_.end()) { | 112 if (it != recently_broken_alternative_services_.end()) { |
113 recently_broken_alternative_services_.Erase(it); | 113 recently_broken_alternative_services_.Erase(it); |
114 } | 114 } |
115 } | 115 } |
116 | 116 |
117 const BrokenAlternativeServiceList& | |
118 BrokenAlternativeServices::broken_alternative_service_list() const { | |
119 return broken_alternative_service_list_; | |
120 } | |
121 | |
122 const RecentlyBrokenAlternativeServices& | |
123 BrokenAlternativeServices::recently_broken_alternative_services() const { | |
124 return recently_broken_alternative_services_; | |
125 } | |
126 | |
127 void BrokenAlternativeServices::AddBrokenAndRecentlyBrokenAlternativeServices( | |
128 std::unique_ptr<BrokenAlternativeServiceList> | |
129 broken_alternative_service_list, | |
130 std::unique_ptr<RecentlyBrokenAlternativeServices> | |
131 recently_broken_alternative_services) { | |
132 // Make sure all alt svcs in |broken_alternative_service_list| has an entry | |
133 // in |recently_broken_alternative_services| | |
134 for (const auto& pair : *broken_alternative_service_list) { | |
135 DCHECK(recently_broken_alternative_services->Peek(pair.first) != | |
136 recently_broken_alternative_services->end()); | |
137 } | |
Zhongyi Shi
2017/06/02 18:19:44
|recently_broken_alternative_services| is an MRUCa
wangyix1
2017/06/05 19:16:25
No, Peek() does not modify the recency list, unlik
Zhongyi Shi
2017/06/06 22:17:49
I miss-read the code, yeah, Peek() should be fine.
wangyix1
2017/06/09 19:26:40
Acknowledged.
| |
138 | |
139 recently_broken_alternative_services_.Swap( | |
140 *recently_broken_alternative_services); | |
141 // Add back all existing recently broken alt svcs to cache so they're at | |
142 // front of recency list. | |
Zhongyi Shi
2017/06/02 18:19:44
I might lose some context but why those existing r
wangyix1
2017/06/05 19:16:24
It's not clear from the name, but this method will
| |
143 for (auto it = recently_broken_alternative_services->rbegin(); | |
144 it != recently_broken_alternative_services->rend(); ++it) { | |
145 if (recently_broken_alternative_services_.Get(it->first) == | |
146 recently_broken_alternative_services_.end()) { | |
147 recently_broken_alternative_services_.Put(it->first, it->second); | |
148 } | |
149 } | |
150 | |
151 // Add broken alt svcs to |broken_alternative_service_map_|. Remove all | |
152 // that already exist in the map. | |
153 auto it = broken_alternative_service_list->begin(); | |
154 while (it != broken_alternative_service_list->end()) { | |
155 const AlternativeService& alternative_service = it->first; | |
156 if (broken_alternative_service_map_.find(alternative_service) == | |
157 broken_alternative_service_map_.end()) { | |
158 broken_alternative_service_map_.insert( | |
159 std::make_pair(alternative_service, it)); | |
160 ++it; | |
161 } else { | |
162 broken_alternative_service_list->erase(it++); | |
163 } | |
164 } | |
165 | |
166 // Merge |broken_alternative_service_list| with | |
167 // |broken_alternative_service_list_|. Both should already be sorted by | |
168 // expiration time. | |
169 bool schedule_expiration = | |
170 (!broken_alternative_service_list->empty() && | |
171 (broken_alternative_service_list_.empty() || | |
172 broken_alternative_service_list->front().second < | |
173 broken_alternative_service_list_.front().second)); | |
174 | |
175 broken_alternative_service_list_.merge( | |
176 *broken_alternative_service_list, | |
177 [](const std::pair<AlternativeService, base::TimeTicks>& lhs, | |
178 const std::pair<AlternativeService, base::TimeTicks>& rhs) -> bool { | |
179 return lhs.second < rhs.second; | |
180 }); | |
181 | |
182 if (schedule_expiration) | |
183 ScheduleBrokenAlternateProtocolMappingsExpiration(); | |
184 } | |
185 | |
117 bool BrokenAlternativeServices::AddToBrokenAlternativeServiceListAndMap( | 186 bool BrokenAlternativeServices::AddToBrokenAlternativeServiceListAndMap( |
118 const AlternativeService& alternative_service, | 187 const AlternativeService& alternative_service, |
119 base::TimeTicks expiration, | 188 base::TimeTicks expiration, |
120 BrokenAlternativeServiceList::iterator* it) { | 189 BrokenAlternativeServiceList::iterator* it) { |
121 DCHECK(it); | 190 DCHECK(it); |
122 | 191 |
123 auto map_it = broken_alternative_service_map_.find(alternative_service); | 192 auto map_it = broken_alternative_service_map_.find(alternative_service); |
124 if (map_it != broken_alternative_service_map_.end()) | 193 if (map_it != broken_alternative_service_map_.end()) |
125 return false; | 194 return false; |
126 | 195 |
127 // Iterate from end of |broken_alternative_service_list_| to find where to | 196 // Iterate from end of |broken_alternative_service_list_| to find where to |
128 // insert it to keep the list sorted by expiration time. | 197 // insert it to keep the list sorted by expiration time. |
129 auto list_it = broken_alternative_service_list_.end(); | 198 auto list_it = broken_alternative_service_list_.end(); |
130 while (list_it != broken_alternative_service_list_.begin()) { | 199 while (list_it != broken_alternative_service_list_.begin()) { |
131 --list_it; | 200 --list_it; |
132 if (list_it->expiration <= expiration) { | 201 if (list_it->second <= expiration) { |
133 ++list_it; | 202 ++list_it; |
134 break; | 203 break; |
135 } | 204 } |
136 } | 205 } |
137 | 206 |
138 // Insert |alternative_service| into the list and the map | 207 // Insert |alternative_service| into the list and the map |
139 list_it = broken_alternative_service_list_.insert( | 208 list_it = broken_alternative_service_list_.insert( |
140 list_it, BrokenAltSvcExpireInfo(alternative_service, expiration)); | 209 list_it, std::make_pair(alternative_service, expiration)); |
141 broken_alternative_service_map_.insert( | 210 broken_alternative_service_map_.insert( |
142 std::make_pair(alternative_service, list_it)); | 211 std::make_pair(alternative_service, list_it)); |
143 | 212 |
144 *it = list_it; | 213 *it = list_it; |
145 return true; | 214 return true; |
146 } | 215 } |
147 | 216 |
148 void BrokenAlternativeServices::ExpireBrokenAlternateProtocolMappings() { | 217 void BrokenAlternativeServices::ExpireBrokenAlternateProtocolMappings() { |
149 base::TimeTicks now = clock_->NowTicks(); | 218 base::TimeTicks now = clock_->NowTicks(); |
150 | 219 |
151 while (!broken_alternative_service_list_.empty()) { | 220 while (!broken_alternative_service_list_.empty()) { |
152 auto it = broken_alternative_service_list_.begin(); | 221 auto it = broken_alternative_service_list_.begin(); |
153 if (now < it->expiration) { | 222 if (now < it->second) { |
154 break; | 223 break; |
155 } | 224 } |
156 | 225 |
157 delegate_->OnExpireBrokenAlternativeService(it->alternative_service); | 226 delegate_->OnExpireBrokenAlternativeService(it->first); |
158 | 227 |
159 broken_alternative_service_map_.erase(it->alternative_service); | 228 broken_alternative_service_map_.erase(it->first); |
160 broken_alternative_service_list_.erase(it); | 229 broken_alternative_service_list_.erase(it); |
161 } | 230 } |
162 | 231 |
163 if (!broken_alternative_service_list_.empty()) | 232 if (!broken_alternative_service_list_.empty()) |
164 ScheduleBrokenAlternateProtocolMappingsExpiration(); | 233 ScheduleBrokenAlternateProtocolMappingsExpiration(); |
165 } | 234 } |
166 | 235 |
167 void BrokenAlternativeServices :: | 236 void BrokenAlternativeServices :: |
168 ScheduleBrokenAlternateProtocolMappingsExpiration() { | 237 ScheduleBrokenAlternateProtocolMappingsExpiration() { |
169 DCHECK(!broken_alternative_service_list_.empty()); | 238 DCHECK(!broken_alternative_service_list_.empty()); |
170 base::TimeTicks now = clock_->NowTicks(); | 239 base::TimeTicks now = clock_->NowTicks(); |
171 base::TimeTicks when = broken_alternative_service_list_.front().expiration; | 240 base::TimeTicks when = broken_alternative_service_list_.front().second; |
172 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 241 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
173 expiration_timer_.Stop(); | 242 expiration_timer_.Stop(); |
174 expiration_timer_.Start( | 243 expiration_timer_.Start( |
175 FROM_HERE, delay, | 244 FROM_HERE, delay, |
176 base::Bind( | 245 base::Bind( |
177 &BrokenAlternativeServices ::ExpireBrokenAlternateProtocolMappings, | 246 &BrokenAlternativeServices ::ExpireBrokenAlternateProtocolMappings, |
178 weak_ptr_factory_.GetWeakPtr())); | 247 weak_ptr_factory_.GetWeakPtr())); |
179 } | 248 } |
180 | 249 |
181 } // namespace net | 250 } // namespace net |
OLD | NEW |