Fix timing of echo acks
This commit is contained in:
@@ -245,13 +245,15 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network
|
|||||||
|
|
||||||
while ( 1 ) {
|
while ( 1 ) {
|
||||||
try {
|
try {
|
||||||
int active_fds = poll( pollfds, 3, network.wait_time() );
|
uint64_t now = Network::timestamp();
|
||||||
|
|
||||||
|
int active_fds = poll( pollfds, 3, min( network.wait_time(), terminal.wait_time( now ) ) );
|
||||||
if ( active_fds < 0 ) {
|
if ( active_fds < 0 ) {
|
||||||
perror( "poll" );
|
perror( "poll" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t now = Network::timestamp();
|
now = Network::timestamp();
|
||||||
|
|
||||||
if ( pollfds[ 0 ].revents & POLLIN ) {
|
if ( pollfds[ 0 ].revents & POLLIN ) {
|
||||||
/* packet received from the network */
|
/* packet received from the network */
|
||||||
@@ -281,8 +283,10 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !us.empty() ) {
|
||||||
/* register input frame number for future echo ack */
|
/* register input frame number for future echo ack */
|
||||||
terminal.register_input_frame( last_remote_num, now );
|
terminal.register_input_frame( last_remote_num, now );
|
||||||
|
}
|
||||||
|
|
||||||
/* update client with new state of terminal */
|
/* update client with new state of terminal */
|
||||||
if ( !network.shutdown_in_progress() ) {
|
if ( !network.shutdown_in_progress() ) {
|
||||||
@@ -399,7 +403,13 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
terminal.set_echo_ack( now );
|
if ( terminal.set_echo_ack( now ) ) {
|
||||||
|
/* update client with new echo ack */
|
||||||
|
if ( !network.shutdown_in_progress() ) {
|
||||||
|
network.set_current_state( terminal );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
network.tick();
|
network.tick();
|
||||||
} catch ( Network::NetworkException e ) {
|
} catch ( Network::NetworkException e ) {
|
||||||
fprintf( stderr, "%s: %s\n", e.function.c_str(), strerror( e.the_errno ) );
|
fprintf( stderr, "%s: %s\n", e.function.c_str(), strerror( e.the_errno ) );
|
||||||
|
|||||||
@@ -104,7 +104,11 @@ int TransportSender<MyState>::wait_time( void )
|
|||||||
{
|
{
|
||||||
calculate_timers();
|
calculate_timers();
|
||||||
|
|
||||||
uint64_t next_wakeup = min( next_ack_time, next_send_time );
|
uint64_t next_wakeup = next_ack_time;
|
||||||
|
if ( next_send_time < next_wakeup ) {
|
||||||
|
next_wakeup = next_send_time;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t now = timestamp();
|
uint64_t now = timestamp();
|
||||||
|
|
||||||
if ( !connection->get_attached() ) {
|
if ( !connection->get_attached() ) {
|
||||||
|
|||||||
@@ -106,8 +106,9 @@ bool Complete::operator==( Complete const &x ) const
|
|||||||
return (terminal == x.terminal) && (echo_ack == x.echo_ack);
|
return (terminal == x.terminal) && (echo_ack == x.echo_ack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Complete::set_echo_ack( uint64_t now )
|
bool Complete::set_echo_ack( uint64_t now )
|
||||||
{
|
{
|
||||||
|
bool ret = false;
|
||||||
uint64_t newest_echo_ack = 0;
|
uint64_t newest_echo_ack = 0;
|
||||||
|
|
||||||
for ( BOOST_AUTO( i, input_history.begin() ); i != input_history.end(); i++ ) {
|
for ( BOOST_AUTO( i, input_history.begin() ); i != input_history.end(); i++ ) {
|
||||||
@@ -118,10 +119,33 @@ void Complete::set_echo_ack( uint64_t now )
|
|||||||
|
|
||||||
input_history.remove_if( (&_1)->*&pair<uint64_t, uint64_t>::first < newest_echo_ack );
|
input_history.remove_if( (&_1)->*&pair<uint64_t, uint64_t>::first < newest_echo_ack );
|
||||||
|
|
||||||
|
if ( echo_ack != newest_echo_ack ) {
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
echo_ack = newest_echo_ack;
|
echo_ack = newest_echo_ack;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Complete::register_input_frame( uint64_t n, uint64_t now )
|
void Complete::register_input_frame( uint64_t n, uint64_t now )
|
||||||
{
|
{
|
||||||
input_history.push_back( make_pair( n, now ) );
|
input_history.push_back( make_pair( n, now ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Complete::wait_time( uint64_t now ) const
|
||||||
|
{
|
||||||
|
if ( input_history.size() < 2 ) {
|
||||||
|
return INT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO( it, input_history.begin() );
|
||||||
|
it++;
|
||||||
|
|
||||||
|
uint64_t next_echo_ack_time = it->second + ECHO_TIMEOUT;
|
||||||
|
if ( next_echo_ack_time <= now ) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return next_echo_ack_time - now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,8 +49,9 @@ namespace Terminal {
|
|||||||
bool parser_grounded( void ) const { return parser.is_grounded(); }
|
bool parser_grounded( void ) const { return parser.is_grounded(); }
|
||||||
|
|
||||||
uint64_t get_echo_ack( void ) const { return echo_ack; }
|
uint64_t get_echo_ack( void ) const { return echo_ack; }
|
||||||
void set_echo_ack( uint64_t now );
|
bool set_echo_ack( uint64_t now );
|
||||||
void register_input_frame( uint64_t n, uint64_t now );
|
void register_input_frame( uint64_t n, uint64_t now );
|
||||||
|
int wait_time( uint64_t now ) const;
|
||||||
|
|
||||||
/* interface for Network::Transport */
|
/* interface for Network::Transport */
|
||||||
void subtract( const Complete * ) {}
|
void subtract( const Complete * ) {}
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ namespace Network {
|
|||||||
void push_back( Parser::UserByte s_userbyte ) { actions.push_back( UserEvent( s_userbyte ) ); }
|
void push_back( Parser::UserByte s_userbyte ) { actions.push_back( UserEvent( s_userbyte ) ); }
|
||||||
void push_back( Parser::Resize s_resize ) { actions.push_back( UserEvent( s_resize ) ); }
|
void push_back( Parser::Resize s_resize ) { actions.push_back( UserEvent( s_resize ) ); }
|
||||||
|
|
||||||
size_t size( void ) { return actions.size(); }
|
bool empty( void ) const { return actions.empty(); }
|
||||||
|
size_t size( void ) const { return actions.size(); }
|
||||||
const Parser::Action *get_action( unsigned int i );
|
const Parser::Action *get_action( unsigned int i );
|
||||||
|
|
||||||
/* interface for Network::Transport */
|
/* interface for Network::Transport */
|
||||||
|
|||||||
Reference in New Issue
Block a user