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:
committed by
Keith Winstein
parent
9dddcd8566
commit
67a85eaf99
@@ -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
@@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user