Deliver sendto() exceptions without disturbing control flow

This prevents the client from waking up every 200 ms while the network is down.
Addresses #243.
This commit is contained in:
Keegan McAllister
2012-05-02 00:14:59 -04:00
committed by Keith Winstein
parent 9dddcd8566
commit 67a85eaf99
4 changed files with 32 additions and 5 deletions
+5
View File
@@ -415,6 +415,11 @@ void STMClient::main( void )
} }
network->tick(); network->tick();
const Network::NetworkException *exn = network->get_send_exception();
if ( exn ) {
overlays.get_notification_engine().set_network_exception( *exn );
}
} catch ( Network::NetworkException e ) { } catch ( Network::NetworkException e ) {
if ( !network->shutdown_in_progress() ) { if ( !network->shutdown_in_progress() ) {
overlays.get_notification_engine().set_network_exception( e ); overlays.get_notification_engine().set_network_exception( e );
+14 -5
View File
@@ -131,7 +131,9 @@ Connection::Connection( const char *desired_ip, const char *desired_port ) /* se
expected_receiver_seq( 0 ), expected_receiver_seq( 0 ),
RTT_hit( false ), RTT_hit( false ),
SRTT( 1000 ), SRTT( 1000 ),
RTTVAR( 500 ) RTTVAR( 500 ),
have_send_exception( false ),
send_exception()
{ {
setup(); setup();
@@ -238,7 +240,9 @@ Connection::Connection( const char *key_str, const char *ip, int port ) /* clien
expected_receiver_seq( 0 ), expected_receiver_seq( 0 ),
RTT_hit( false ), RTT_hit( false ),
SRTT( 1000 ), SRTT( 1000 ),
RTTVAR( 500 ) RTTVAR( 500 ),
have_send_exception( false ),
send_exception()
{ {
setup(); setup();
@@ -266,9 +270,14 @@ void Connection::send( string s )
ssize_t bytes_sent = sendto( sock, p.data(), p.size(), 0, ssize_t bytes_sent = sendto( sock, p.data(), p.size(), 0,
(sockaddr *)&remote_addr, sizeof( remote_addr ) ); (sockaddr *)&remote_addr, sizeof( remote_addr ) );
if ( (!server) /* Server treats all sendto()s as successful. */ if ( bytes_sent == static_cast<ssize_t>( p.size() ) ) {
&& (bytes_sent != static_cast<ssize_t>( p.size() )) ) { have_send_exception = false;
throw NetworkException( "sendto", errno ); } else {
/* Notify the frontend on sendto() failure, but don't alter control flow.
sendto() success is not very meaningful because packets can be lost in
flight anyway. */
have_send_exception = true;
send_exception = NetworkException( "sendto", errno );
} }
} }
+11
View File
@@ -42,6 +42,7 @@ namespace Network {
string function; string function;
int the_errno; int the_errno;
NetworkException( string s_function, int s_errno ) : function( s_function ), the_errno( s_errno ) {} NetworkException( string s_function, int s_errno ) : function( s_function ), the_errno( s_errno ) {}
NetworkException() : function( "<none>" ), the_errno( 0 ) {}
}; };
enum Direction { enum Direction {
@@ -101,6 +102,11 @@ namespace Network {
double SRTT; double SRTT;
double RTTVAR; double RTTVAR;
/* Exception from send(), to be delivered if the frontend asks for it,
without altering control flow. */
bool have_send_exception;
NetworkException send_exception;
Packet new_packet( string &s_payload ); Packet new_packet( string &s_payload );
public: public:
@@ -121,6 +127,11 @@ namespace Network {
double get_SRTT( void ) const { return SRTT; } double get_SRTT( void ) const { return SRTT; }
const struct in_addr & get_remote_ip( void ) const { return remote_addr.sin_addr; } const struct in_addr & get_remote_ip( void ) const { return remote_addr.sin_addr; }
const NetworkException *get_send_exception( void ) const
{
return have_send_exception ? &send_exception : NULL;
}
}; };
} }
+2
View File
@@ -102,6 +102,8 @@ namespace Network {
unsigned int send_interval( void ) const { return sender.send_interval(); } unsigned int send_interval( void ) const { return sender.send_interval(); }
const struct in_addr & get_remote_ip( void ) const { return connection.get_remote_ip(); } const struct in_addr & get_remote_ip( void ) const { return connection.get_remote_ip(); }
const NetworkException *get_send_exception( void ) const { return connection.get_send_exception(); }
}; };
} }