Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: net/quic/chromium/quic_chromium_client_session.cc

Issue 2848923004: Move the "wait for QUIC handshake confirmation" logic to QuicChromiumClientSession::StreamRequest (Closed)
Patch Set: fix Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/quic/chromium/quic_chromium_client_session.h" 5 #include "net/quic/chromium/quic_chromium_client_session.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 const GURL& GetURL() const override { return request_url_; } 180 const GURL& GetURL() const override { return request_url_; }
181 181
182 private: 182 private:
183 base::WeakPtr<QuicChromiumClientSession> session_; 183 base::WeakPtr<QuicChromiumClientSession> session_;
184 const GURL request_url_; 184 const GURL request_url_;
185 }; 185 };
186 186
187 } // namespace 187 } // namespace
188 188
189 QuicChromiumClientSession::StreamRequest::StreamRequest( 189 QuicChromiumClientSession::StreamRequest::StreamRequest(
190 const base::WeakPtr<QuicChromiumClientSession>& session) 190 const base::WeakPtr<QuicChromiumClientSession>& session,
191 : session_(session), stream_(nullptr) {} 191 bool requires_confirmation)
192 : session_(session),
193 requires_confirmation_(requires_confirmation),
194 stream_(nullptr),
195 next_state_(STATE_NONE),
196 weak_factory_(this) {}
192 197
193 QuicChromiumClientSession::StreamRequest::~StreamRequest() { 198 QuicChromiumClientSession::StreamRequest::~StreamRequest() {
194 if (stream_) 199 if (stream_)
195 stream_->Reset(QUIC_STREAM_CANCELLED); 200 stream_->Reset(QUIC_STREAM_CANCELLED);
196 201
197 if (session_) 202 if (session_)
198 session_->CancelRequest(this); 203 session_->CancelRequest(this);
199 } 204 }
200 205
201 int QuicChromiumClientSession::StreamRequest::StartRequest( 206 int QuicChromiumClientSession::StreamRequest::StartRequest(
202 const CompletionCallback& callback) { 207 const CompletionCallback& callback) {
203 DCHECK(session_); 208 DCHECK(session_);
204 int rv = session_->TryCreateStream(this); 209
205 if (rv == ERR_IO_PENDING) { 210 next_state_ = STATE_WAIT_FOR_CONFIRMATION;
211 int rv = DoLoop(OK);
212 if (rv == ERR_IO_PENDING)
206 callback_ = callback; 213 callback_ = callback;
207 } else {
208 session_.reset();
209 }
210 214
211 return rv; 215 return rv;
212 } 216 }
213 217
214 QuicChromiumClientStream* 218 QuicChromiumClientStream*
215 QuicChromiumClientSession::StreamRequest::ReleaseStream() { 219 QuicChromiumClientSession::StreamRequest::ReleaseStream() {
216 DCHECK(stream_); 220 DCHECK(stream_);
217 QuicChromiumClientStream* stream = stream_; 221 QuicChromiumClientStream* stream = stream_;
218 stream_ = nullptr; 222 stream_ = nullptr;
219 return stream; 223 return stream;
220 } 224 }
221 225
222 void QuicChromiumClientSession::StreamRequest::OnRequestCompleteSuccess( 226 void QuicChromiumClientSession::StreamRequest::OnRequestCompleteSuccess(
223 QuicChromiumClientStream* stream) { 227 QuicChromiumClientStream* stream) {
228 DCHECK_EQ(STATE_REQUEST_STREAM_COMPLETE, next_state_);
224 session_.reset(); 229 session_.reset();
225 stream_ = stream; 230 stream_ = stream;
226 base::ResetAndReturn(&callback_).Run(OK); 231 // This method is called even when the request completes synchronously.
232 if (callback_)
233 DoCallback(OK);
227 } 234 }
228 235
229 void QuicChromiumClientSession::StreamRequest::OnRequestCompleteFailure( 236 void QuicChromiumClientSession::StreamRequest::OnRequestCompleteFailure(
230 int rv) { 237 int rv) {
238 DCHECK_EQ(STATE_REQUEST_STREAM_COMPLETE, next_state_);
231 session_.reset(); 239 session_.reset();
240 // This method is called even when the request completes synchronously.
241 if (callback_)
242 DoCallback(rv);
243 }
244
245 void QuicChromiumClientSession::StreamRequest::OnIOComplete(int rv) {
246 rv = DoLoop(rv);
247
248 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
249 DoCallback(rv);
250 }
251 }
252
253 void QuicChromiumClientSession::StreamRequest::DoCallback(int rv) {
254 CHECK_NE(rv, ERR_IO_PENDING);
255 CHECK(!callback_.is_null());
256
257 // The client callback can do anything, including destroying this class,
258 // so any pending callback must be issued after everything else is done.
232 base::ResetAndReturn(&callback_).Run(rv); 259 base::ResetAndReturn(&callback_).Run(rv);
233 } 260 }
234 261
262 int QuicChromiumClientSession::StreamRequest::DoLoop(int rv) {
263 do {
264 State state = next_state_;
265 next_state_ = STATE_NONE;
266 switch (state) {
267 case STATE_WAIT_FOR_CONFIRMATION:
268 CHECK_EQ(OK, rv);
269 rv = DoWaitForConfirmation();
270 break;
271 case STATE_WAIT_FOR_CONFIRMATION_COMPLETE:
272 rv = DoWaitForConfirmationComplete(rv);
273 break;
274 case STATE_REQUEST_STREAM:
275 CHECK_EQ(OK, rv);
276 rv = DoRequestStream();
277 break;
278 case STATE_REQUEST_STREAM_COMPLETE:
279 rv = DoRequestStreamComplete(rv);
280 break;
281 default:
282 NOTREACHED() << "next_state_: " << next_state_;
283 break;
284 }
285 } while (next_state_ != STATE_NONE && next_state_ && rv != ERR_IO_PENDING);
286
287 return rv;
288 }
289
290 int QuicChromiumClientSession::StreamRequest::DoWaitForConfirmation() {
291 next_state_ = STATE_WAIT_FOR_CONFIRMATION_COMPLETE;
292 if (requires_confirmation_) {
293 return session_->WaitForHandshakeConfirmation(
294 base::Bind(&QuicChromiumClientSession::StreamRequest::OnIOComplete,
295 weak_factory_.GetWeakPtr()));
296 }
297
298 return OK;
299 }
300
301 int QuicChromiumClientSession::StreamRequest::DoWaitForConfirmationComplete(
302 int rv) {
303 DCHECK_NE(ERR_IO_PENDING, rv);
304 if (rv < 0)
305 return rv;
306
307 next_state_ = STATE_REQUEST_STREAM;
308 return OK;
309 }
310
311 int QuicChromiumClientSession::StreamRequest::DoRequestStream() {
312 next_state_ = STATE_REQUEST_STREAM_COMPLETE;
313
314 return session_->TryCreateStream(this);
315 }
316
317 int QuicChromiumClientSession::StreamRequest::DoRequestStreamComplete(int rv) {
318 DCHECK(rv == OK || !stream_);
319 session_.reset();
320
321 return rv;
322 }
323
235 QuicChromiumClientSession::QuicChromiumClientSession( 324 QuicChromiumClientSession::QuicChromiumClientSession(
236 QuicConnection* connection, 325 QuicConnection* connection,
237 std::unique_ptr<DatagramClientSocket> socket, 326 std::unique_ptr<DatagramClientSocket> socket,
238 QuicStreamFactory* stream_factory, 327 QuicStreamFactory* stream_factory,
239 QuicCryptoClientStreamFactory* crypto_client_stream_factory, 328 QuicCryptoClientStreamFactory* crypto_client_stream_factory,
240 QuicClock* clock, 329 QuicClock* clock,
241 TransportSecurityState* transport_security_state, 330 TransportSecurityState* transport_security_state,
242 std::unique_ptr<QuicServerInfo> server_info, 331 std::unique_ptr<QuicServerInfo> server_info,
243 const QuicServerId& server_id, 332 const QuicServerId& server_id,
244 bool require_confirmation, 333 bool require_confirmation,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 kAdditionalOverheadForIPv6); 389 kAdditionalOverheadForIPv6);
301 } 390 }
302 connect_timing_.dns_start = dns_resolution_start_time; 391 connect_timing_.dns_start = dns_resolution_start_time;
303 connect_timing_.dns_end = dns_resolution_end_time; 392 connect_timing_.dns_end = dns_resolution_end_time;
304 } 393 }
305 394
306 QuicChromiumClientSession::~QuicChromiumClientSession() { 395 QuicChromiumClientSession::~QuicChromiumClientSession() {
307 DCHECK(callback_.is_null()); 396 DCHECK(callback_.is_null());
308 397
309 net_log_.EndEvent(NetLogEventType::QUIC_SESSION); 398 net_log_.EndEvent(NetLogEventType::QUIC_SESSION);
399 DCHECK(waiting_for_confirmation_callbacks_.empty());
310 if (!dynamic_streams().empty()) 400 if (!dynamic_streams().empty())
311 RecordUnexpectedOpenStreams(DESTRUCTOR); 401 RecordUnexpectedOpenStreams(DESTRUCTOR);
312 if (!observers_.empty()) 402 if (!observers_.empty())
313 RecordUnexpectedObservers(DESTRUCTOR); 403 RecordUnexpectedObservers(DESTRUCTOR);
314 if (!going_away_) 404 if (!going_away_)
315 RecordUnexpectedNotGoingAway(DESTRUCTOR); 405 RecordUnexpectedNotGoingAway(DESTRUCTOR);
316 406
317 while (!dynamic_streams().empty() || !observers_.empty() || 407 while (!dynamic_streams().empty() || !observers_.empty() ||
318 !stream_requests_.empty()) { 408 !stream_requests_.empty()) {
319 // The session must be closed before it is destroyed. 409 // The session must be closed before it is destroyed.
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 DCHECK(!base::ContainsKey(observers_, observer)); 538 DCHECK(!base::ContainsKey(observers_, observer));
449 observers_.insert(observer); 539 observers_.insert(observer);
450 } 540 }
451 541
452 void QuicChromiumClientSession::RemoveObserver(Observer* observer) { 542 void QuicChromiumClientSession::RemoveObserver(Observer* observer) {
453 DCHECK(base::ContainsKey(observers_, observer)); 543 DCHECK(base::ContainsKey(observers_, observer));
454 observers_.erase(observer); 544 observers_.erase(observer);
455 } 545 }
456 546
457 std::unique_ptr<QuicChromiumClientSession::StreamRequest> 547 std::unique_ptr<QuicChromiumClientSession::StreamRequest>
458 QuicChromiumClientSession::CreateStreamRequest() { 548 QuicChromiumClientSession::CreateStreamRequest(bool requires_confirmation) {
459 // base::MakeUnique does not work because the StreamRequest constructor 549 // base::MakeUnique does not work because the StreamRequest constructor
460 // is private. 550 // is private.
461 return std::unique_ptr<StreamRequest>( 551 return std::unique_ptr<StreamRequest>(
462 new StreamRequest(weak_factory_.GetWeakPtr())); 552 new StreamRequest(weak_factory_.GetWeakPtr(), requires_confirmation));
553 }
554
555 int QuicChromiumClientSession::WaitForHandshakeConfirmation(
556 const CompletionCallback& callback) {
557 if (!connection()->connected())
558 return ERR_CONNECTION_CLOSED;
559
560 if (IsCryptoHandshakeConfirmed())
561 return OK;
562
563 waiting_for_confirmation_callbacks_.push_back(callback);
564 return ERR_IO_PENDING;
463 } 565 }
464 566
465 int QuicChromiumClientSession::TryCreateStream(StreamRequest* request) { 567 int QuicChromiumClientSession::TryCreateStream(StreamRequest* request) {
466 if (goaway_received()) { 568 if (goaway_received()) {
467 DVLOG(1) << "Going away."; 569 DVLOG(1) << "Going away.";
468 return ERR_CONNECTION_CLOSED; 570 return ERR_CONNECTION_CLOSED;
469 } 571 }
470 572
471 if (!connection()->connected()) { 573 if (!connection()->connected()) {
472 DVLOG(1) << "Already closed."; 574 DVLOG(1) << "Already closed.";
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 "Net.QuicSession.HostResolution.HandshakeConfirmedTime", 959 "Net.QuicSession.HostResolution.HandshakeConfirmedTime",
858 base::TimeTicks::Now() - connect_timing_.dns_end); 960 base::TimeTicks::Now() - connect_timing_.dns_end);
859 } 961 }
860 962
861 ObserverSet::iterator it = observers_.begin(); 963 ObserverSet::iterator it = observers_.begin();
862 while (it != observers_.end()) { 964 while (it != observers_.end()) {
863 Observer* observer = *it; 965 Observer* observer = *it;
864 ++it; 966 ++it;
865 observer->OnCryptoHandshakeConfirmed(); 967 observer->OnCryptoHandshakeConfirmed();
866 } 968 }
969
970 NotifyRequestsOfConfirmation(OK);
867 } 971 }
868 QuicSpdySession::OnCryptoHandshakeEvent(event); 972 QuicSpdySession::OnCryptoHandshakeEvent(event);
869 } 973 }
870 974
871 void QuicChromiumClientSession::OnCryptoHandshakeMessageSent( 975 void QuicChromiumClientSession::OnCryptoHandshakeMessageSent(
872 const CryptoHandshakeMessage& message) { 976 const CryptoHandshakeMessage& message) {
873 logger_->OnCryptoHandshakeMessageSent(message); 977 logger_->OnCryptoHandshakeMessageSent(message);
874 } 978 }
875 979
876 void QuicChromiumClientSession::OnCryptoHandshakeMessageReceived( 980 void QuicChromiumClientSession::OnCryptoHandshakeMessageReceived(
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 base::ResetAndReturn(&callback_).Run(ERR_QUIC_PROTOCOL_ERROR); 1103 base::ResetAndReturn(&callback_).Run(ERR_QUIC_PROTOCOL_ERROR);
1000 } 1104 }
1001 1105
1002 for (auto& socket : sockets_) { 1106 for (auto& socket : sockets_) {
1003 socket->Close(); 1107 socket->Close();
1004 } 1108 }
1005 DCHECK(dynamic_streams().empty()); 1109 DCHECK(dynamic_streams().empty());
1006 CloseAllStreams(ERR_UNEXPECTED); 1110 CloseAllStreams(ERR_UNEXPECTED);
1007 CloseAllObservers(ERR_UNEXPECTED); 1111 CloseAllObservers(ERR_UNEXPECTED);
1008 CancelAllRequests(ERR_CONNECTION_CLOSED); 1112 CancelAllRequests(ERR_CONNECTION_CLOSED);
1113 NotifyRequestsOfConfirmation(ERR_CONNECTION_CLOSED);
1009 NotifyFactoryOfSessionClosedLater(); 1114 NotifyFactoryOfSessionClosedLater();
1010 } 1115 }
1011 1116
1012 void QuicChromiumClientSession::OnSuccessfulVersionNegotiation( 1117 void QuicChromiumClientSession::OnSuccessfulVersionNegotiation(
1013 const QuicVersion& version) { 1118 const QuicVersion& version) {
1014 logger_->OnSuccessfulVersionNegotiation(version); 1119 logger_->OnSuccessfulVersionNegotiation(version);
1015 QuicSpdySession::OnSuccessfulVersionNegotiation(version); 1120 QuicSpdySession::OnSuccessfulVersionNegotiation(version);
1016 1121
1017 ObserverSet::iterator it = observers_.begin(); 1122 ObserverSet::iterator it = observers_.begin();
1018 while (it != observers_.end()) { 1123 while (it != observers_.end()) {
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 UMA_HISTOGRAM_COUNTS_1000("Net.QuicSession.AbortedPendingStreamRequests", 1363 UMA_HISTOGRAM_COUNTS_1000("Net.QuicSession.AbortedPendingStreamRequests",
1259 stream_requests_.size()); 1364 stream_requests_.size());
1260 1365
1261 while (!stream_requests_.empty()) { 1366 while (!stream_requests_.empty()) {
1262 StreamRequest* request = stream_requests_.front(); 1367 StreamRequest* request = stream_requests_.front();
1263 stream_requests_.pop_front(); 1368 stream_requests_.pop_front();
1264 request->OnRequestCompleteFailure(net_error); 1369 request->OnRequestCompleteFailure(net_error);
1265 } 1370 }
1266 } 1371 }
1267 1372
1373 void QuicChromiumClientSession::NotifyRequestsOfConfirmation(int net_error) {
1374 // Post tasks to avoid reentrancy.
1375 for (auto callback : waiting_for_confirmation_callbacks_)
1376 task_runner_->PostTask(FROM_HERE, base::Bind(callback, net_error));
1377
1378 waiting_for_confirmation_callbacks_.clear();
1379 }
1380
1268 std::unique_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue( 1381 std::unique_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue(
1269 const std::set<HostPortPair>& aliases) { 1382 const std::set<HostPortPair>& aliases) {
1270 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 1383 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
1271 dict->SetString("version", QuicVersionToString(connection()->version())); 1384 dict->SetString("version", QuicVersionToString(connection()->version()));
1272 dict->SetInteger("open_streams", GetNumOpenOutgoingStreams()); 1385 dict->SetInteger("open_streams", GetNumOpenOutgoingStreams());
1273 std::unique_ptr<base::ListValue> stream_list(new base::ListValue()); 1386 std::unique_ptr<base::ListValue> stream_list(new base::ListValue());
1274 for (DynamicStreamMap::const_iterator it = dynamic_streams().begin(); 1387 for (DynamicStreamMap::const_iterator it = dynamic_streams().begin();
1275 it != dynamic_streams().end(); ++it) { 1388 it != dynamic_streams().end(); ++it) {
1276 stream_list->AppendString(base::UintToString(it->second->id())); 1389 stream_list->AppendString(base::UintToString(it->second->id()));
1277 } 1390 }
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 } 1601 }
1489 1602
1490 size_t QuicChromiumClientSession::EstimateMemoryUsage() const { 1603 size_t QuicChromiumClientSession::EstimateMemoryUsage() const {
1491 // TODO(xunjieli): Estimate |crypto_stream_|, QuicSpdySession's 1604 // TODO(xunjieli): Estimate |crypto_stream_|, QuicSpdySession's
1492 // QuicHeaderList, QuicSession's QuiCWriteBlockedList, open streams and 1605 // QuicHeaderList, QuicSession's QuiCWriteBlockedList, open streams and
1493 // unacked packet map. 1606 // unacked packet map.
1494 return base::trace_event::EstimateMemoryUsage(packet_readers_); 1607 return base::trace_event::EstimateMemoryUsage(packet_readers_);
1495 } 1608 }
1496 1609
1497 } // namespace net 1610 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/chromium/quic_chromium_client_session.h ('k') | net/quic/chromium/quic_chromium_client_session_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698