Wrap boost::exception with fc::exception in fc::ip::endpoint::from_string()

Restructure udp_socket::receive_from() to something functionally identical, but has one less exception handler on the stack which I hope would make it easier to debug strange exception-handling errors encountered on win64
This commit is contained in:
Eric Frias 2014-09-08 16:10:42 -04:00
parent 10fdbcf5b3
commit 881903c1be
2 changed files with 39 additions and 27 deletions

View file

@ -1,5 +1,6 @@
#include <fc/network/ip.hpp>
#include <fc/variant.hpp>
#include <fc/exception/exception.hpp>
#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
@ -55,12 +56,17 @@ namespace fc { namespace ip {
uint16_t endpoint::port()const { return _port; }
const address& endpoint::get_address()const { return _ip; }
endpoint endpoint::from_string( const string& endpoint_string ) {
endpoint ep;
auto pos = endpoint_string.find(':');
ep._ip = boost::asio::ip::address_v4::from_string(endpoint_string.substr( 0, pos ) ).to_ulong();
ep._port = boost::lexical_cast<uint16_t>( endpoint_string.substr( pos+1, endpoint_string.size() ) );
return ep;
endpoint endpoint::from_string( const string& endpoint_string )
{
try
{
endpoint ep;
auto pos = endpoint_string.find(':');
ep._ip = boost::asio::ip::address_v4::from_string(endpoint_string.substr( 0, pos ) ).to_ulong();
ep._port = boost::lexical_cast<uint16_t>( endpoint_string.substr( pos+1, endpoint_string.size() ) );
return ep;
}
FC_RETHROW_EXCEPTIONS(warn, "error converting string to IP endpoint")
}
endpoint::operator string()const {

View file

@ -73,30 +73,36 @@ namespace fc {
void udp_socket::bind( const fc::ip::endpoint& e ) {
my->_sock.bind( to_asio_ep(e) );
}
size_t udp_socket::receive_from( char* b, size_t l, fc::ip::endpoint& _from ) {
try {
boost::asio::ip::udp::endpoint from;
size_t r = my->_sock.receive_from( boost::asio::buffer(b, l), from );
_from = to_fc_ep(from);
return r;
} catch( const boost::system::system_error& e ) {
if( e.code() == boost::asio::error::would_block ) {
boost::asio::ip::udp::endpoint from;
promise<size_t>::ptr p(new promise<size_t>("udp_socket::send_to"));
my->_sock.async_receive_from( boost::asio::buffer(b,l), from,
[=]( const boost::system::error_code& ec, size_t bytes_transferred ) {
if( !ec ) p->set_value(bytes_transferred);
else p->set_exception( fc::exception_ptr( new fc::exception(
FC_LOG_MESSAGE( error, "${message} ",
("message", boost::system::system_error(ec).what())) ) ) );
});
auto r = p->wait();
_from = to_fc_ep(from);
return r;
}
size_t udp_socket::receive_from( char* receive_buffer, size_t receive_buffer_length, fc::ip::endpoint& from )
{
try
{
boost::asio::ip::udp::endpoint boost_from_endpoint;
size_t bytes_read = my->_sock.receive_from( boost::asio::buffer(receive_buffer, receive_buffer_length), boost_from_endpoint );
from = to_fc_ep(boost_from_endpoint);
return bytes_read;
}
catch( const boost::system::system_error& e )
{
if( e.code() != boost::asio::error::would_block )
throw;
}
boost::asio::ip::udp::endpoint boost_from_endpoint;
promise<size_t>::ptr completion_promise(new promise<size_t>("udp_socket::receive_from"));
my->_sock.async_receive_from( boost::asio::buffer(receive_buffer, receive_buffer_length), boost_from_endpoint,
[=]( const boost::system::error_code& ec, size_t bytes_transferred ) {
if( !ec )
completion_promise->set_value(bytes_transferred);
else
completion_promise->set_exception( fc::exception_ptr( new fc::exception( FC_LOG_MESSAGE( error, "${message} ",
("message", boost::system::system_error(ec).what())) ) ) );
});
size_t bytes_read = completion_promise->wait();
from = to_fc_ep(boost_from_endpoint);
return bytes_read;
}
void udp_socket::close() {
//my->_sock.cancel();
my->_sock.close();