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

Unified 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, 8 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 side-by-side diff with in-line comments
Download patch
Index: net/quic/chromium/quic_chromium_client_session.cc
diff --git a/net/quic/chromium/quic_chromium_client_session.cc b/net/quic/chromium/quic_chromium_client_session.cc
index f7555d843d44c9c56e8aadf76d815448907e7967..cd123b19de48d537ea0477a194e63ba669259869 100644
--- a/net/quic/chromium/quic_chromium_client_session.cc
+++ b/net/quic/chromium/quic_chromium_client_session.cc
@@ -187,8 +187,13 @@ class QuicServerPushHelper : public ServerPushDelegate::ServerPushHelper {
} // namespace
QuicChromiumClientSession::StreamRequest::StreamRequest(
- const base::WeakPtr<QuicChromiumClientSession>& session)
- : session_(session), stream_(nullptr) {}
+ const base::WeakPtr<QuicChromiumClientSession>& session,
+ bool requires_confirmation)
+ : session_(session),
+ requires_confirmation_(requires_confirmation),
+ stream_(nullptr),
+ next_state_(STATE_NONE),
+ weak_factory_(this) {}
QuicChromiumClientSession::StreamRequest::~StreamRequest() {
if (stream_)
@@ -201,12 +206,11 @@ QuicChromiumClientSession::StreamRequest::~StreamRequest() {
int QuicChromiumClientSession::StreamRequest::StartRequest(
const CompletionCallback& callback) {
DCHECK(session_);
- int rv = session_->TryCreateStream(this);
- if (rv == ERR_IO_PENDING) {
+
+ next_state_ = STATE_WAIT_FOR_CONFIRMATION;
+ int rv = DoLoop(OK);
+ if (rv == ERR_IO_PENDING)
callback_ = callback;
- } else {
- session_.reset();
- }
return rv;
}
@@ -221,17 +225,102 @@ QuicChromiumClientSession::StreamRequest::ReleaseStream() {
void QuicChromiumClientSession::StreamRequest::OnRequestCompleteSuccess(
QuicChromiumClientStream* stream) {
+ DCHECK_EQ(STATE_REQUEST_STREAM_COMPLETE, next_state_);
session_.reset();
stream_ = stream;
- base::ResetAndReturn(&callback_).Run(OK);
+ // This method is called even when the request completes synchronously.
+ if (callback_)
+ DoCallback(OK);
}
void QuicChromiumClientSession::StreamRequest::OnRequestCompleteFailure(
int rv) {
+ DCHECK_EQ(STATE_REQUEST_STREAM_COMPLETE, next_state_);
session_.reset();
+ // This method is called even when the request completes synchronously.
+ if (callback_)
+ DoCallback(rv);
+}
+
+void QuicChromiumClientSession::StreamRequest::OnIOComplete(int rv) {
+ rv = DoLoop(rv);
+
+ if (rv != ERR_IO_PENDING && !callback_.is_null()) {
+ DoCallback(rv);
+ }
+}
+
+void QuicChromiumClientSession::StreamRequest::DoCallback(int rv) {
+ CHECK_NE(rv, ERR_IO_PENDING);
+ CHECK(!callback_.is_null());
+
+ // The client callback can do anything, including destroying this class,
+ // so any pending callback must be issued after everything else is done.
base::ResetAndReturn(&callback_).Run(rv);
}
+int QuicChromiumClientSession::StreamRequest::DoLoop(int rv) {
+ do {
+ State state = next_state_;
+ next_state_ = STATE_NONE;
+ switch (state) {
+ case STATE_WAIT_FOR_CONFIRMATION:
+ CHECK_EQ(OK, rv);
+ rv = DoWaitForConfirmation();
+ break;
+ case STATE_WAIT_FOR_CONFIRMATION_COMPLETE:
+ rv = DoWaitForConfirmationComplete(rv);
+ break;
+ case STATE_REQUEST_STREAM:
+ CHECK_EQ(OK, rv);
+ rv = DoRequestStream();
+ break;
+ case STATE_REQUEST_STREAM_COMPLETE:
+ rv = DoRequestStreamComplete(rv);
+ break;
+ default:
+ NOTREACHED() << "next_state_: " << next_state_;
+ break;
+ }
+ } while (next_state_ != STATE_NONE && next_state_ && rv != ERR_IO_PENDING);
+
+ return rv;
+}
+
+int QuicChromiumClientSession::StreamRequest::DoWaitForConfirmation() {
+ next_state_ = STATE_WAIT_FOR_CONFIRMATION_COMPLETE;
+ if (requires_confirmation_) {
+ return session_->WaitForHandshakeConfirmation(
+ base::Bind(&QuicChromiumClientSession::StreamRequest::OnIOComplete,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ return OK;
+}
+
+int QuicChromiumClientSession::StreamRequest::DoWaitForConfirmationComplete(
+ int rv) {
+ DCHECK_NE(ERR_IO_PENDING, rv);
+ if (rv < 0)
+ return rv;
+
+ next_state_ = STATE_REQUEST_STREAM;
+ return OK;
+}
+
+int QuicChromiumClientSession::StreamRequest::DoRequestStream() {
+ next_state_ = STATE_REQUEST_STREAM_COMPLETE;
+
+ return session_->TryCreateStream(this);
+}
+
+int QuicChromiumClientSession::StreamRequest::DoRequestStreamComplete(int rv) {
+ DCHECK(rv == OK || !stream_);
+ session_.reset();
+
+ return rv;
+}
+
QuicChromiumClientSession::QuicChromiumClientSession(
QuicConnection* connection,
std::unique_ptr<DatagramClientSocket> socket,
@@ -307,6 +396,7 @@ QuicChromiumClientSession::~QuicChromiumClientSession() {
DCHECK(callback_.is_null());
net_log_.EndEvent(NetLogEventType::QUIC_SESSION);
+ DCHECK(waiting_for_confirmation_callbacks_.empty());
if (!dynamic_streams().empty())
RecordUnexpectedOpenStreams(DESTRUCTOR);
if (!observers_.empty())
@@ -455,11 +545,23 @@ void QuicChromiumClientSession::RemoveObserver(Observer* observer) {
}
std::unique_ptr<QuicChromiumClientSession::StreamRequest>
-QuicChromiumClientSession::CreateStreamRequest() {
+QuicChromiumClientSession::CreateStreamRequest(bool requires_confirmation) {
// base::MakeUnique does not work because the StreamRequest constructor
// is private.
return std::unique_ptr<StreamRequest>(
- new StreamRequest(weak_factory_.GetWeakPtr()));
+ new StreamRequest(weak_factory_.GetWeakPtr(), requires_confirmation));
+}
+
+int QuicChromiumClientSession::WaitForHandshakeConfirmation(
+ const CompletionCallback& callback) {
+ if (!connection()->connected())
+ return ERR_CONNECTION_CLOSED;
+
+ if (IsCryptoHandshakeConfirmed())
+ return OK;
+
+ waiting_for_confirmation_callbacks_.push_back(callback);
+ return ERR_IO_PENDING;
}
int QuicChromiumClientSession::TryCreateStream(StreamRequest* request) {
@@ -864,6 +966,8 @@ void QuicChromiumClientSession::OnCryptoHandshakeEvent(
++it;
observer->OnCryptoHandshakeConfirmed();
}
+
+ NotifyRequestsOfConfirmation(OK);
}
QuicSpdySession::OnCryptoHandshakeEvent(event);
}
@@ -1006,6 +1110,7 @@ void QuicChromiumClientSession::OnConnectionClosed(
CloseAllStreams(ERR_UNEXPECTED);
CloseAllObservers(ERR_UNEXPECTED);
CancelAllRequests(ERR_CONNECTION_CLOSED);
+ NotifyRequestsOfConfirmation(ERR_CONNECTION_CLOSED);
NotifyFactoryOfSessionClosedLater();
}
@@ -1265,6 +1370,14 @@ void QuicChromiumClientSession::CancelAllRequests(int net_error) {
}
}
+void QuicChromiumClientSession::NotifyRequestsOfConfirmation(int net_error) {
+ // Post tasks to avoid reentrancy.
+ for (auto callback : waiting_for_confirmation_callbacks_)
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, net_error));
+
+ waiting_for_confirmation_callbacks_.clear();
+}
+
std::unique_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue(
const std::set<HostPortPair>& aliases) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
« 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