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

Unified Diff: net/quic/quic_connection.cc

Issue 138843003: Eliminate separate boolean tracking socket writeability in (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 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
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_connection.cc
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index 49d6af61380853cd5a6a814d24a3f4cfe9251145..479373ed9a4e6e392e6c1eccf2c2ce8484fd1b8f 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -166,7 +166,6 @@ QuicConnection::QuicConnection(QuicGuid guid,
peer_address_(address),
largest_seen_packet_with_ack_(0),
pending_version_negotiation_packet_(false),
- write_blocked_(false),
received_packet_manager_(kTCP),
ack_alarm_(helper->CreateAlarm(new AckAlarm(this))),
retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))),
@@ -772,9 +771,6 @@ void QuicConnection::SendVersionNegotiationPacket() {
WriteResult result =
writer_->WritePacket(version_packet->data(), version_packet->length(),
self_address().address(), peer_address(), this);
- if (result.status == WRITE_STATUS_BLOCKED) {
- write_blocked_ = true;
- }
if (result.status == WRITE_STATUS_OK ||
(result.status == WRITE_STATUS_BLOCKED &&
writer_->IsWriteBlockedDataBuffered())) {
@@ -881,21 +877,9 @@ void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address,
}
bool QuicConnection::OnCanWrite() {
- write_blocked_ = false;
- return DoWrite();
-}
-
-bool QuicConnection::WriteIfNotBlocked() {
- if (write_blocked_) {
- return false;
- }
- return DoWrite();
-}
+ DCHECK(!writer_->IsWriteBlocked());
-bool QuicConnection::DoWrite() {
- DCHECK(!write_blocked_);
WriteQueuedPackets();
-
WritePendingRetransmissions();
IsHandshake pending_handshake = visitor_->HasPendingHandshake() ?
@@ -925,7 +909,13 @@ bool QuicConnection::DoWrite() {
}
}
- return !write_blocked_;
+ return !writer_->IsWriteBlocked();
+}
+
+void QuicConnection::WriteIfNotBlocked() {
+ if (!writer_->IsWriteBlocked()) {
+ OnCanWrite();
+ }
}
bool QuicConnection::ProcessValidatedPacket() {
@@ -946,15 +936,16 @@ bool QuicConnection::ProcessValidatedPacket() {
return true;
}
-bool QuicConnection::WriteQueuedPackets() {
- DCHECK(!write_blocked_);
+void QuicConnection::WriteQueuedPackets() {
+ DCHECK(!writer_->IsWriteBlocked());
if (pending_version_negotiation_packet_) {
SendVersionNegotiationPacket();
}
QueuedPacketList::iterator packet_iterator = queued_packets_.begin();
- while (!write_blocked_ && packet_iterator != queued_packets_.end()) {
+ while (!writer_->IsWriteBlocked() &&
+ packet_iterator != queued_packets_.end()) {
if (WritePacket(packet_iterator->encryption_level,
packet_iterator->sequence_number,
packet_iterator->packet,
@@ -962,15 +953,14 @@ bool QuicConnection::WriteQueuedPackets() {
packet_iterator->retransmittable,
packet_iterator->handshake,
packet_iterator->forced)) {
+ delete packet_iterator->packet;
packet_iterator = queued_packets_.erase(packet_iterator);
} else {
// Continue, because some queued packets may still be writable.
- // This can happen if a retransmit send fail.
+ // This can happen if a retransmit send fails.
++packet_iterator;
}
}
-
- return !write_blocked_;
}
void QuicConnection::WritePendingRetransmissions() {
@@ -1035,7 +1025,7 @@ bool QuicConnection::ShouldGeneratePacket(
bool QuicConnection::CanWrite(TransmissionType transmission_type,
HasRetransmittableData retransmittable,
IsHandshake handshake) {
- if (write_blocked_) {
+ if (writer_->IsWriteBlocked()) {
return false;
}
@@ -1073,16 +1063,13 @@ bool QuicConnection::WritePacket(EncryptionLevel level,
IsHandshake handshake,
Force forced) {
if (ShouldDiscardPacket(level, sequence_number, retransmittable)) {
- delete packet;
return true;
}
- // If we're write blocked, we know we can't write.
- if (write_blocked_) {
- return false;
- }
-
- // If we are not forced and we can't write, then simply return false;
+ // If the writer is blocked, we must not write. However, if the packet is
+ // forced (i.e., it's the ConnectionClose packet), we still need to encrypt it
+ // and hand it off to TimeWaitListManager.
+ // We check nonforced packets here and forced after encryption.
if (forced == NO_FORCE &&
!CanWrite(transmission_type, retransmittable, handshake)) {
return false;
@@ -1098,20 +1085,29 @@ bool QuicConnection::WritePacket(EncryptionLevel level,
sequence_number_of_last_inorder_packet_ = sequence_number;
}
- scoped_ptr<QuicEncryptedPacket> encrypted(
- framer_.EncryptPacket(level, sequence_number, *packet));
- if (encrypted.get() == NULL) {
+ QuicEncryptedPacket* encrypted =
+ framer_.EncryptPacket(level, sequence_number, *packet);
+ if (encrypted == NULL) {
LOG(DFATAL) << ENDPOINT << "Failed to encrypt packet number "
<< sequence_number;
+ // CloseConnection does not send close packet, so no infinite loop here.
CloseConnection(QUIC_ENCRYPTION_FAILURE, false);
return false;
}
- // If it's the ConnectionClose packet, the only FORCED frame type,
- // clone a copy for resending later by the TimeWaitListManager.
- if (forced == FORCE) {
+ // Forced packets are eventually owned by TimeWaitListManager; nonforced are
+ // deleted at the end of this call.
+ scoped_ptr<QuicEncryptedPacket> encrypted_deleter;
+ if (forced == NO_FORCE) {
+ encrypted_deleter.reset(encrypted);
+ } else { // forced == FORCE
DCHECK(connection_close_packet_.get() == NULL);
- connection_close_packet_.reset(encrypted->Clone());
+ connection_close_packet_.reset(encrypted);
+ // This assures we won't try to write *forced* packets when blocked.
+ // Return true to stop processing.
+ if (writer_->IsWriteBlocked()) {
+ return true;
+ }
}
if (encrypted->length() > options()->max_packet_length) {
@@ -1153,16 +1149,11 @@ bool QuicConnection::WritePacket(EncryptionLevel level,
debug_visitor_->OnPacketSent(sequence_number, level, *encrypted, result);
}
if (result.status == WRITE_STATUS_BLOCKED) {
- // TODO(satyashekhar): It might be more efficient (fewer system calls), if
- // all connections share this variable i.e this becomes a part of
- // PacketWriterInterface.
- write_blocked_ = true;
// If the socket buffers the the data, then the packet should not
// be queued and sent again, which would result in an unnecessary
// duplicate packet being sent. The helper must call OnPacketSent
// when the packet is actually sent.
if (writer_->IsWriteBlockedDataBuffered()) {
- delete packet;
return true;
}
pending_write_.reset();
@@ -1170,7 +1161,6 @@ bool QuicConnection::WritePacket(EncryptionLevel level,
}
if (OnPacketSent(result)) {
- delete packet;
return true;
}
return false;
@@ -1318,6 +1308,7 @@ bool QuicConnection::SendOrQueuePacket(EncryptionLevel level,
packet.entropy_hash);
if (WritePacket(level, packet.sequence_number, packet.packet,
transmission_type, retransmittable, handshake, forced)) {
+ delete packet.packet;
return true;
}
queued_packets_.push_back(QueuedPacket(packet.sequence_number, packet.packet,
@@ -1487,9 +1478,9 @@ void QuicConnection::SendConnectionClose(QuicErrorCode error) {
void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error,
const string& details) {
- if (!write_blocked_) {
- SendConnectionClosePacket(error, details);
- }
+ // If we're write blocked, WritePacket() will not send, but will capture the
+ // serialized packet.
+ SendConnectionClosePacket(error, details);
CloseConnection(error, false);
}
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698