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

Side by Side Diff: net/quic/quic_sent_packet_manager.cc

Issue 137923007: Refactor QuicSentPacketManager::MarkPacketHandled to simplify (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_connection_test.cc ('k') | net/quic/quic_sent_packet_manager_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/quic_sent_packet_manager.h" 5 #include "net/quic/quic_sent_packet_manager.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "net/quic/congestion_control/pacing_sender.h" 9 #include "net/quic/congestion_control/pacing_sender.h"
10 #include "net/quic/crypto/crypto_protocol.h" 10 #include "net/quic/crypto/crypto_protocol.h"
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 const TransmissionInfo& transmission_info) { 361 const TransmissionInfo& transmission_info) {
362 if (transmission_info.retransmittable_frames == NULL) { 362 if (transmission_info.retransmittable_frames == NULL) {
363 return false; 363 return false;
364 } 364 }
365 return transmission_info.retransmittable_frames->HasCryptoHandshake() == 365 return transmission_info.retransmittable_frames->HasCryptoHandshake() ==
366 IS_HANDSHAKE; 366 IS_HANDSHAKE;
367 } 367 }
368 368
369 QuicSentPacketManager::UnackedPacketMap::iterator 369 QuicSentPacketManager::UnackedPacketMap::iterator
370 QuicSentPacketManager::MarkPacketHandled( 370 QuicSentPacketManager::MarkPacketHandled(
371 QuicPacketSequenceNumber sequence_number, ReceivedByPeer received_by_peer) { 371 QuicPacketSequenceNumber sequence_number,
372 DCHECK(ContainsKey(unacked_packets_, sequence_number)); 372 ReceivedByPeer received_by_peer) {
373 373 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number);
374 if (it == unacked_packets_.end()) {
375 LOG(DFATAL) << "Packet is not unacked: " << sequence_number;
376 return it;
377 }
374 // If this packet is pending, remove it and inform the send algorithm. 378 // If this packet is pending, remove it and inform the send algorithm.
375 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number);
376 if (it->second.pending) { 379 if (it->second.pending) {
377 size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent(); 380 size_t bytes_sent = packet_history_map_[sequence_number]->bytes_sent();
378 if (received_by_peer == RECEIVED_BY_PEER) { 381 if (received_by_peer == RECEIVED_BY_PEER) {
379 send_algorithm_->OnPacketAcked(sequence_number, bytes_sent); 382 send_algorithm_->OnPacketAcked(sequence_number, bytes_sent);
380 } else { 383 } else {
381 // It's been abandoned. 384 // It's been abandoned.
382 send_algorithm_->OnPacketAbandoned(sequence_number, bytes_sent); 385 send_algorithm_->OnPacketAbandoned(sequence_number, bytes_sent);
383 } 386 }
384 it->second.pending = false; 387 it->second.pending = false;
385 } 388 }
386 389
387 // If this packet has never been retransmitted, then simply drop it. 390 SequenceNumberSet* previous_transmissions = it->second.previous_transmissions;
388 if (it->second.previous_transmissions == NULL) { 391 if (previous_transmissions == NULL) {
389 ++it; 392 previous_transmissions = new SequenceNumberSet;
390 DiscardPacket(sequence_number); 393 previous_transmissions->insert(sequence_number);
391 return it;
392 } 394 }
393
394 SequenceNumberSet* previous_transmissions = it->second.previous_transmissions;
395 DCHECK(!previous_transmissions->empty()); 395 DCHECK(!previous_transmissions->empty());
396 SequenceNumberSet::reverse_iterator previous_transmissions_it = 396 SequenceNumberSet::reverse_iterator previous_transmissions_it =
397 previous_transmissions->rbegin(); 397 previous_transmissions->rbegin();
398 QuicPacketSequenceNumber newest_transmission = *previous_transmissions_it; 398 QuicPacketSequenceNumber newest_transmission = *previous_transmissions_it;
399 TransmissionInfo* transmission_info =
400 FindOrNull(unacked_packets_, newest_transmission);
401 if (newest_transmission != sequence_number) { 399 if (newest_transmission != sequence_number) {
402 ++stats_->packets_spuriously_retransmitted; 400 ++stats_->packets_spuriously_retransmitted;
403 } 401 }
404 if (newest_transmission == sequence_number) { 402
405 DiscardPacket(newest_transmission); 403 bool has_cryto_handshake = HasCryptoHandshake(
406 } else if (HasCryptoHandshake(*transmission_info)) { 404 *FindOrNull(unacked_packets_, newest_transmission));
407 // If it's a crypto handshake packet, discard it and all retransmissions, 405 if (has_cryto_handshake) {
408 // since they won't be acked now that one has been processed. 406 --pending_crypto_packet_count_;
409 if (transmission_info->pending) {
410 OnPacketAbandoned(unacked_packets_.find(newest_transmission));
411 }
412 DiscardPacket(newest_transmission);
413 } else {
414 // If we have received an ack for a previous transmission of a packet,
415 // we want to keep the "new" transmission of the packet unacked,
416 // but prevent the data from being retransmitted.
417 delete transmission_info->retransmittable_frames;
418 transmission_info->retransmittable_frames = NULL;
419 transmission_info->previous_transmissions = NULL;
420 } 407 }
421
422 // Clear out information all previous transmissions unless they're pending.
423 ++previous_transmissions_it;
424 while (previous_transmissions_it != previous_transmissions->rend()) { 408 while (previous_transmissions_it != previous_transmissions->rend()) {
425 QuicPacketSequenceNumber previous_transmission = *previous_transmissions_it; 409 QuicPacketSequenceNumber previous_transmission = *previous_transmissions_it;
410 TransmissionInfo* transmission_info =
411 FindOrNull(unacked_packets_, previous_transmission);
412 if (transmission_info->retransmittable_frames != NULL) {
413 // Since some version of this packet has been acked, ensure that
414 // the data is not retransmitted again.
415 delete transmission_info->retransmittable_frames;
416 transmission_info->retransmittable_frames = NULL;
417 }
418 if (ContainsKey(pending_retransmissions_, previous_transmission)) {
419 // Don't bother retransmitting this packet, if it has been
420 // marked for retransmission.
421 pending_retransmissions_.erase(previous_transmission);
422 }
423 if (has_cryto_handshake) {
424 // If it's a crypto handshake packet, discard it and all retransmissions,
425 // since they won't be acked now that one has been processed.
426 if (transmission_info->pending) {
427 OnPacketAbandoned(unacked_packets_.find(newest_transmission));
428 }
429 transmission_info->pending = false;
430 }
431 if (!transmission_info->pending) {
432 unacked_packets_.erase(previous_transmission);
433 } else {
434 transmission_info->previous_transmissions = NULL;
435 }
426 ++previous_transmissions_it; 436 ++previous_transmissions_it;
427 // If the packet was TLP retransmitted, the old copy is still pending.
428 // Keep it until it is lost or acked.
429 if (unacked_packets_[previous_transmission].pending) {
430 // Previous transmissions will be deleted, so set it to NULL.
431 unacked_packets_[previous_transmission].previous_transmissions = NULL;
432 } else {
433 DiscardPacket(previous_transmission);
434 }
435 } 437 }
436
437 delete previous_transmissions; 438 delete previous_transmissions;
438 439
439 if (ContainsKey(pending_retransmissions_, newest_transmission)) {
440 pending_retransmissions_.erase(newest_transmission);
441 if (!unacked_packets_[newest_transmission].pending) {
442 // If the newest transmission has already been marked for retransmission
443 // and has already been abandoned, then we should remove it from
444 // unacked_packets_, as well as cancel the retransmission.
445 DCHECK(ContainsKey(unacked_packets_, newest_transmission));
446 DCHECK(!unacked_packets_[newest_transmission].previous_transmissions);
447 unacked_packets_.erase(newest_transmission);
448 }
449 }
450
451 UnackedPacketMap::iterator next_unacked = unacked_packets_.begin(); 440 UnackedPacketMap::iterator next_unacked = unacked_packets_.begin();
452 while (next_unacked != unacked_packets_.end() && 441 while (next_unacked != unacked_packets_.end() &&
453 next_unacked->first < sequence_number) { 442 next_unacked->first < sequence_number) {
454 ++next_unacked; 443 ++next_unacked;
455 } 444 }
456 return next_unacked; 445 return next_unacked;
457 } 446 }
458 447
459 void QuicSentPacketManager::DiscardPacket(
460 QuicPacketSequenceNumber sequence_number) {
461 UnackedPacketMap::iterator unacked_it =
462 unacked_packets_.find(sequence_number);
463 DCHECK(unacked_it != unacked_packets_.end());
464 // Ensure the packet is no longer pending when it's discarded.
465 DCHECK(!unacked_it->second.pending);
466
467 RetransmittableFrames* retransmittable_frames =
468 unacked_it->second.retransmittable_frames;
469 if (HasCryptoHandshake(unacked_it->second)) {
470 --pending_crypto_packet_count_;
471 }
472
473 // Delete the retransmittable frames.
474 delete retransmittable_frames;
475 unacked_packets_.erase(unacked_it);
476 pending_retransmissions_.erase(sequence_number);
477 return;
478 }
479
480 bool QuicSentPacketManager::IsUnacked( 448 bool QuicSentPacketManager::IsUnacked(
481 QuicPacketSequenceNumber sequence_number) const { 449 QuicPacketSequenceNumber sequence_number) const {
482 return ContainsKey(unacked_packets_, sequence_number); 450 return ContainsKey(unacked_packets_, sequence_number);
483 } 451 }
484 452
485 bool QuicSentPacketManager::HasUnackedPackets() const { 453 bool QuicSentPacketManager::HasUnackedPackets() const {
486 return !unacked_packets_.empty(); 454 return !unacked_packets_.empty();
487 } 455 }
488 456
489 bool QuicSentPacketManager::HasPendingPackets() const { 457 bool QuicSentPacketManager::HasPendingPackets() const {
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 } 938 }
971 previous_transmissions->erase(sequence_number); 939 previous_transmissions->erase(sequence_number);
972 if (previous_transmissions->size() == 1) { 940 if (previous_transmissions->size() == 1) {
973 QuicPacketSequenceNumber current = *previous_transmissions->begin(); 941 QuicPacketSequenceNumber current = *previous_transmissions->begin();
974 unacked_packets_[current].previous_transmissions = NULL; 942 unacked_packets_[current].previous_transmissions = NULL;
975 delete previous_transmissions; 943 delete previous_transmissions;
976 } 944 }
977 } 945 }
978 946
979 } // namespace net 947 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_connection_test.cc ('k') | net/quic/quic_sent_packet_manager_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698