Improve client shutdown robustness

This commit is contained in:
Keith Winstein
2011-09-30 03:01:14 -04:00
parent 0d85b410fe
commit 31577a1c16
4 changed files with 39 additions and 3 deletions
+1
View File
@@ -55,6 +55,7 @@ namespace Network {
void start_shutdown( void ) { sender.start_shutdown(); }
bool shutdown_in_progress( void ) { return sender.get_shutdown_in_progress(); }
bool shutdown_acknowledged( void ) { return sender.get_shutdown_acknowledged(); }
bool shutdown_ack_timed_out( void ) { return sender.shutdown_ack_timed_out(); }
bool attached( void ) { return connection.get_attached(); }
/* Other side has requested shutdown and we have sent one ACK */
+20 -2
View File
@@ -227,7 +227,16 @@ void STMClient::main( void )
if ( pollfds[ 3 ].revents & POLLIN ) {
/* shutdown signal */
if ( network->attached() ) {
struct signalfd_siginfo the_siginfo;
ssize_t bytes_read = read( pollfds[ 3 ].fd, &the_siginfo, sizeof( the_siginfo ) );
if ( bytes_read == 0 ) {
break;
} else if ( bytes_read < 0 ) {
perror( "read" );
break;
}
if ( network->attached() && (!network->shutdown_in_progress()) ) {
network->start_shutdown();
} else {
break;
@@ -243,7 +252,11 @@ void STMClient::main( void )
if ( (pollfds[ 1 ].revents)
& (POLLERR | POLLHUP | POLLNVAL) ) {
/* user problem */
network->start_shutdown();
if ( network->attached() && (!network->shutdown_in_progress()) ) {
network->start_shutdown();
} else {
break;
}
}
/* quit if our shutdown has been acknowledged */
@@ -251,6 +264,11 @@ void STMClient::main( void )
break;
}
/* quit after shutdown acknowledgement timeout */
if ( network->shutdown_in_progress() && network->shutdown_ack_timed_out() ) {
break;
}
/* quit if we received and acknowledged a shutdown request */
if ( network->counterparty_shutdown_ack_sent() ) {
break;
+15
View File
@@ -14,6 +14,7 @@ TransportSender<MyState>::TransportSender( Connection *s_connection, MyState &in
next_send_time( timestamp() ),
verbose( false ),
shutdown_in_progress( false ),
shutdown_timestamp( -1 ),
ack_num( 0 ),
pending_data_ack( false )
{
@@ -279,3 +280,17 @@ void TransportSender<MyState>::process_acknowledgment_through( uint64_t ack_num
assert( !sent_states.empty() );
}
/* give up on getting acknowledgement for shutdown after 5 RTTs */
template <class MyState>
bool TransportSender<MyState>::shutdown_ack_timed_out( void )
{
if ( !shutdown_in_progress ) {
return false;
}
if ( timestamp() - shutdown_timestamp > 5 * connection->get_SRTT() ) {
return true;
}
return false;
}
+3 -1
View File
@@ -55,6 +55,7 @@ namespace Network {
bool verbose;
bool shutdown_in_progress;
uint64_t shutdown_timestamp;
/* information about receiver state */
uint64_t ack_num;
@@ -80,7 +81,7 @@ namespace Network {
void set_data_ack( void ) { pending_data_ack = true; }
/* Starts shutdown sequence */
void start_shutdown( void ) { shutdown_in_progress = true; }
void start_shutdown( void ) { shutdown_in_progress = true; shutdown_timestamp = timestamp(); }
/* Misc. getters and setters */
/* Cannot modify current_state while shutdown in progress */
@@ -91,6 +92,7 @@ namespace Network {
bool get_shutdown_in_progress( void ) { return shutdown_in_progress; }
bool get_shutdown_acknowledged( void ) { return sent_states.front().num == uint64_t(-1); }
bool get_counterparty_shutdown_acknowledged( void ) { return fragmenter.last_ack_sent() == uint64_t(-1); }
bool shutdown_ack_timed_out( void );
/* nonexistent methods to satisfy -Weffc++ */
TransportSender( const TransportSender &x );