#include #include #include #include namespace fc { namespace asio { namespace detail { void read_write_handler( const promise::ptr& p, const boost::system::error_code& ec, size_t bytes_transferred ) { if( !ec ) p->set_value(bytes_transferred); else { // elog( "%s", boost::system::system_error(ec).what() ); // p->set_exception( fc::copy_exception( boost::system::system_error(ec) ) ); if( ec == boost::asio::error::operation_aborted ) { p->set_exception( fc::exception_ptr( new fc::canceled_exception( FC_LOG_MESSAGE( error, "${message} ", ("message", boost::system::system_error(ec).what())) ) ) ); } else if( ec == boost::asio::error::eof ) { p->set_exception( fc::exception_ptr( new fc::eof_exception( FC_LOG_MESSAGE( error, "${message} ", ("message", boost::system::system_error(ec).what())) ) ) ); } else { // elog( "${message} ", ("message", boost::system::system_error(ec).what())); p->set_exception( fc::exception_ptr( new fc::exception( FC_LOG_MESSAGE( error, "${message} ", ("message", boost::system::system_error(ec).what())) ) ) ); } } } void read_write_handler_ec( promise* p, boost::system::error_code* oec, const boost::system::error_code& ec, size_t bytes_transferred ) { p->set_value(bytes_transferred); *oec = ec; } void error_handler( const promise::ptr& p, const boost::system::error_code& ec ) { if( !ec ) p->set_value(); else { if( ec == boost::asio::error::operation_aborted ) { p->set_exception( fc::exception_ptr( new fc::canceled_exception( FC_LOG_MESSAGE( error, "${message} ", ("message", boost::system::system_error(ec).what())) ) ) ); } else if( ec == boost::asio::error::eof ) { p->set_exception( fc::exception_ptr( new fc::eof_exception( FC_LOG_MESSAGE( error, "${message} ", ("message", boost::system::system_error(ec).what())) ) ) ); } else { // elog( "${message} ", ("message", boost::system::system_error(ec).what())); p->set_exception( fc::exception_ptr( new fc::exception( FC_LOG_MESSAGE( error, "${message} ", ("message", boost::system::system_error(ec).what())) ) ) ); } } } void error_handler_ec( promise* p, const boost::system::error_code& ec ) { p->set_value(ec); } template void resolve_handler( const typename promise >::ptr& p, const boost::system::error_code& ec, IteratorType itr) { if( !ec ) { std::vector eps; while( itr != IteratorType() ) { eps.push_back(*itr); ++itr; } p->set_value( eps ); } else { //elog( "%s", boost::system::system_error(ec).what() ); //p->set_exception( fc::copy_exception( boost::system::system_error(ec) ) ); p->set_exception( fc::exception_ptr( new fc::exception( FC_LOG_MESSAGE( error, "process exited with: ${message} ", ("message", boost::system::system_error(ec).what())) ) ) ); } } } struct default_io_service_scope { boost::asio::io_service* io; boost::thread* asio_thread; boost::asio::io_service::work* the_work; default_io_service_scope() { io = new boost::asio::io_service(); the_work = new boost::asio::io_service::work(*io); asio_thread = new boost::thread( [=]() { fc::thread::current().set_name("asio"); io->run(); }); } ~default_io_service_scope() { delete the_work; io->stop(); // TODO: this hangs sometimes.. asio_thread->join(); delete io; delete asio_thread; } }; boost::asio::io_service& default_io_service(bool cleanup) { static default_io_service_scope fc_asio_service; return *fc_asio_service.io; } namespace tcp { std::vector resolve( const std::string& hostname, const std::string& port) { resolver res( fc::asio::default_io_service() ); promise >::ptr p( new promise >() ); res.async_resolve( boost::asio::ip::tcp::resolver::query(hostname,port), boost::bind( detail::resolve_handler, p, _1, _2 ) ); return p->wait();; } } namespace udp { std::vector resolve( resolver& r, const std::string& hostname, const std::string& port) { resolver res( fc::asio::default_io_service() ); promise >::ptr p( new promise >() ); res.async_resolve( resolver::query(hostname,port), boost::bind( detail::resolve_handler, p, _1, _2 ) ); return p->wait(); } } } } // namespace fc::asio