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::SetBrokenAndRecentlyBrokenAlternativeServices( | |
128 std::unique_ptr<BrokenAlternativeServiceList> | |
129 broken_alternative_service_list, | |
130 std::unique_ptr<RecentlyBrokenAlternativeServices> | |
131 recently_broken_alternative_services) { | |
132 DCHECK(broken_alternative_service_list); | |
133 DCHECK(recently_broken_alternative_services); | |
134 | |
135 // Make sure all alt svcs in |broken_alternative_service_list| has an entry | |
136 // in |recently_broken_alternative_services| | |
137 for (const auto& pair : *broken_alternative_service_list) { | |
138 DCHECK(recently_broken_alternative_services->Peek(pair.first) != | |
139 recently_broken_alternative_services->end()); | |
140 } | |
141 | |
142 base::TimeTicks next_expiration = | |
143 broken_alternative_service_list_.empty() | |
144 ? base::TimeTicks::Max() | |
145 : broken_alternative_service_list_.front().second; | |
146 | |
147 // Add recently broken alt svcs to |recently_broken_alternative_services_|. | |
148 // If an alt-svc already exists, update its broken-count to the one provided | |
149 // in |recently_broken_alternative_services|. | |
150 | |
151 recently_broken_alternative_services_.Swap( | |
152 *recently_broken_alternative_services); | |
153 // Add back all existing recently broken alt svcs to cache so they're at | |
154 // front of recency list (MRUCache::Get() does this automatically). | |
155 for (auto it = recently_broken_alternative_services->rbegin(); | |
156 it != recently_broken_alternative_services->rend(); ++it) { | |
157 if (recently_broken_alternative_services_.Get(it->first) == | |
158 recently_broken_alternative_services_.end()) { | |
159 recently_broken_alternative_services_.Put(it->first, it->second); | |
160 } | |
161 } | |
162 | |
163 // Add broken alt svcs to |broken_alternative_service_map_|. If an entry | |
164 // already exists, delete its corresponding entry in | |
165 // |broken_alternative_service_list_| and update its map entry to point to | |
166 // its position in |broken_alternative_service_list|. | |
Zhongyi Shi
2017/06/12 23:20:38
This method has no guarantee on when it will be ca
wangyix1
2017/06/13 01:17:46
If some data exists in both cache and disk, I curr
Zhongyi Shi
2017/06/13 21:45:22
Urm, I don't think we could assume before disk loa
Ryan Hamilton
2017/06/19 17:05:35
I think we should be consistent with the behavior
wangyix1
2017/06/19 19:47:35
The other setters in HttpServerPropertiesImpl() al
| |
167 for (auto it = broken_alternative_service_list->begin(); | |
168 it != broken_alternative_service_list->end(); ++it) { | |
169 const AlternativeService& alternative_service = it->first; | |
170 auto map_it = broken_alternative_service_map_.find(alternative_service); | |
171 if (map_it != broken_alternative_service_map_.end()) { | |
172 broken_alternative_service_list_.erase(map_it->second); | |
173 map_it->second = it; | |
174 } else { | |
175 broken_alternative_service_map_.insert( | |
176 std::make_pair(alternative_service, it)); | |
177 } | |
178 } | |
179 | |
180 // Merge |broken_alternative_service_list| with | |
181 // |broken_alternative_service_list_|. Both should already be sorted by | |
182 // expiration time. std::list::merge() will not invalidate any iterators | |
183 // of either list, so all iterators in |broken_alternative_service_map_| | |
184 // remain valid. | |
185 broken_alternative_service_list_.merge( | |
186 *broken_alternative_service_list, | |
187 [](const std::pair<AlternativeService, base::TimeTicks>& lhs, | |
188 const std::pair<AlternativeService, base::TimeTicks>& rhs) -> bool { | |
189 return lhs.second < rhs.second; | |
190 }); | |
191 | |
192 base::TimeTicks new_next_expiration = | |
193 broken_alternative_service_list_.empty() | |
194 ? base::TimeTicks::Max() | |
195 : broken_alternative_service_list_.front().second; | |
196 | |
197 if (new_next_expiration != next_expiration) | |
198 ScheduleBrokenAlternateProtocolMappingsExpiration(); | |
199 } | |
200 | |
117 bool BrokenAlternativeServices::AddToBrokenAlternativeServiceListAndMap( | 201 bool BrokenAlternativeServices::AddToBrokenAlternativeServiceListAndMap( |
118 const AlternativeService& alternative_service, | 202 const AlternativeService& alternative_service, |
119 base::TimeTicks expiration, | 203 base::TimeTicks expiration, |
120 BrokenAlternativeServiceList::iterator* it) { | 204 BrokenAlternativeServiceList::iterator* it) { |
121 DCHECK(it); | 205 DCHECK(it); |
122 | 206 |
123 auto map_it = broken_alternative_service_map_.find(alternative_service); | 207 auto map_it = broken_alternative_service_map_.find(alternative_service); |
124 if (map_it != broken_alternative_service_map_.end()) | 208 if (map_it != broken_alternative_service_map_.end()) |
125 return false; | 209 return false; |
126 | 210 |
127 // Iterate from end of |broken_alternative_service_list_| to find where to | 211 // Iterate from end of |broken_alternative_service_list_| to find where to |
128 // insert it to keep the list sorted by expiration time. | 212 // insert it to keep the list sorted by expiration time. |
129 auto list_it = broken_alternative_service_list_.end(); | 213 auto list_it = broken_alternative_service_list_.end(); |
130 while (list_it != broken_alternative_service_list_.begin()) { | 214 while (list_it != broken_alternative_service_list_.begin()) { |
131 --list_it; | 215 --list_it; |
132 if (list_it->expiration <= expiration) { | 216 if (list_it->second <= expiration) { |
133 ++list_it; | 217 ++list_it; |
134 break; | 218 break; |
135 } | 219 } |
136 } | 220 } |
137 | 221 |
138 // Insert |alternative_service| into the list and the map | 222 // Insert |alternative_service| into the list and the map |
139 list_it = broken_alternative_service_list_.insert( | 223 list_it = broken_alternative_service_list_.insert( |
140 list_it, BrokenAltSvcExpireInfo(alternative_service, expiration)); | 224 list_it, std::make_pair(alternative_service, expiration)); |
141 broken_alternative_service_map_.insert( | 225 broken_alternative_service_map_.insert( |
142 std::make_pair(alternative_service, list_it)); | 226 std::make_pair(alternative_service, list_it)); |
143 | 227 |
144 *it = list_it; | 228 *it = list_it; |
145 return true; | 229 return true; |
146 } | 230 } |
147 | 231 |
148 void BrokenAlternativeServices::ExpireBrokenAlternateProtocolMappings() { | 232 void BrokenAlternativeServices::ExpireBrokenAlternateProtocolMappings() { |
149 base::TimeTicks now = clock_->NowTicks(); | 233 base::TimeTicks now = clock_->NowTicks(); |
150 | 234 |
151 while (!broken_alternative_service_list_.empty()) { | 235 while (!broken_alternative_service_list_.empty()) { |
152 auto it = broken_alternative_service_list_.begin(); | 236 auto it = broken_alternative_service_list_.begin(); |
153 if (now < it->expiration) { | 237 if (now < it->second) { |
154 break; | 238 break; |
155 } | 239 } |
156 | 240 |
157 delegate_->OnExpireBrokenAlternativeService(it->alternative_service); | 241 delegate_->OnExpireBrokenAlternativeService(it->first); |
158 | 242 |
159 broken_alternative_service_map_.erase(it->alternative_service); | 243 broken_alternative_service_map_.erase(it->first); |
160 broken_alternative_service_list_.erase(it); | 244 broken_alternative_service_list_.erase(it); |
161 } | 245 } |
162 | 246 |
163 if (!broken_alternative_service_list_.empty()) | 247 if (!broken_alternative_service_list_.empty()) |
164 ScheduleBrokenAlternateProtocolMappingsExpiration(); | 248 ScheduleBrokenAlternateProtocolMappingsExpiration(); |
165 } | 249 } |
166 | 250 |
167 void BrokenAlternativeServices :: | 251 void BrokenAlternativeServices :: |
168 ScheduleBrokenAlternateProtocolMappingsExpiration() { | 252 ScheduleBrokenAlternateProtocolMappingsExpiration() { |
169 DCHECK(!broken_alternative_service_list_.empty()); | 253 DCHECK(!broken_alternative_service_list_.empty()); |
170 base::TimeTicks now = clock_->NowTicks(); | 254 base::TimeTicks now = clock_->NowTicks(); |
171 base::TimeTicks when = broken_alternative_service_list_.front().expiration; | 255 base::TimeTicks when = broken_alternative_service_list_.front().second; |
172 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 256 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
173 expiration_timer_.Stop(); | 257 expiration_timer_.Stop(); |
174 expiration_timer_.Start( | 258 expiration_timer_.Start( |
175 FROM_HERE, delay, | 259 FROM_HERE, delay, |
176 base::Bind( | 260 base::Bind( |
177 &BrokenAlternativeServices ::ExpireBrokenAlternateProtocolMappings, | 261 &BrokenAlternativeServices ::ExpireBrokenAlternateProtocolMappings, |
178 weak_ptr_factory_.GetWeakPtr())); | 262 weak_ptr_factory_.GetWeakPtr())); |
179 } | 263 } |
180 | 264 |
181 } // namespace net | 265 } // namespace net |
OLD | NEW |