From 271e6b8fc2e2adc852949167a84bcdb95dd3fd97 Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Tue, 27 Sep 2011 00:36:04 -0400 Subject: [PATCH] Restrain growth of sent_states queue --- TODO | 2 +- transportsender.cpp | 28 +++++++++++++++++++++++++--- transportsender.hpp | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index f50de46..443bbea 100644 --- a/TODO +++ b/TODO @@ -6,7 +6,7 @@ [DONE] Graceful exit / server shutdown -Don't let sent_states grow without bound for long-sleeping clients +[DONE] Don't let sent_states grow without bound for long-sleeping clients Make roaming much smoother (with error message placement) diff --git a/transportsender.cpp b/transportsender.cpp index 7cba7b1..81f1593 100644 --- a/transportsender.cpp +++ b/transportsender.cpp @@ -121,11 +121,25 @@ void TransportSender::send_empty_ack( void ) new_num = uint64_t( -1 ); } + // sent_states.push_back( TimestampedState( sent_states.back().timestamp, new_num, current_state ) ); + add_sent_state( sent_states.back().timestamp, new_num, current_state ); send_in_fragments( "", new_num ); - sent_states.push_back( TimestampedState( sent_states.back().timestamp, new_num, current_state ) ); + next_ack_time = timestamp() + ACK_INTERVAL; } +template +void TransportSender::add_sent_state( uint64_t the_timestamp, uint64_t num, MyState &state ) +{ + sent_states.push_back( TimestampedState( the_timestamp, num, state ) ); + if ( sent_states.size() > 32 ) { /* limit on state queue */ + auto last = sent_states.end(); + last--; + last--; + sent_states.erase( last ); /* erase penultimate state */ + } +} + template void TransportSender::send_to_receiver( string diff ) { @@ -153,7 +167,8 @@ void TransportSender::send_to_receiver( string diff ) if ( new_num == sent_states.back().num ) { sent_states.back().timestamp = timestamp(); } else { - sent_states.push_back( TimestampedState( timestamp(), new_num, current_state ) ); + // sent_states.push_back( TimestampedState( timestamp(), new_num, current_state ) ); + add_sent_state( timestamp(), new_num, current_state ); } try { @@ -243,6 +258,13 @@ void TransportSender::send_in_fragments( string diff, uint64_t new_num template void TransportSender::process_acknowledgment_through( uint64_t ack_num ) { + /* Check if state being acknowledged is one we have culled */ + assert( !sent_states.empty() ); + + if ( sent_states.back().num < ack_num ) { + return; + } + typename list< TimestampedState >::iterator i = sent_states.begin(); while ( i != sent_states.end() ) { typename list< TimestampedState >::iterator inext = i; @@ -253,6 +275,6 @@ void TransportSender::process_acknowledgment_through( uint64_t ack_num i = inext; } - assert( sent_states.size() > 0 ); + assert( !sent_states.empty() ); } diff --git a/transportsender.hpp b/transportsender.hpp index e5b83bd..4ad4bd0 100644 --- a/transportsender.hpp +++ b/transportsender.hpp @@ -32,6 +32,7 @@ namespace Network { void send_to_receiver( string diff ); void send_empty_ack( void ); void send_in_fragments( string diff, uint64_t new_num ); + void add_sent_state( uint64_t the_timestamp, uint64_t num, MyState &state ); /* state of sender */ Connection *connection;