#include #include #include #include #include #include #include #include // crtl-c handler namespace { void sleep(int sec) { boost::timed_mutex m; boost::condition c; boost::xtime t; boost::timed_mutex::scoped_lock lk(m); boost::xtime_get(&t,1); t.sec += sec; c.timed_wait(lk,t); } sig_atomic_t ctrl_req = 1; void sig_handler(int sig) { if (SIGINT == sig) { //ctrl_req = 0; signal(SIGINT, SIG_DFL); std::cout << "hello" << std::endl; } } boost::function0 shutdown_handler; boost::timed_mutex ctrl_mx; boost::condition ctrl_cond; void ctrl_poll() { boost::xtime t; boost::timed_mutex::scoped_lock lk(ctrl_mx); while (0 != ctrl_req) { boost::xtime_get(&t, 1); t.sec += 1; ctrl_cond.timed_wait(lk,t); } shutdown_handler(); } } namespace aio = boost::asio; namespace ip = boost::asio::ip; namespace sys = boost::system; ip::tcp::resolver::iterator resolve_it; std::size_t received_count; aio::io_service* pio; ip::tcp::resolver* pres; ip::tcp::socket* psock; void handle_resolve ( const sys::error_code& e , ip::tcp::resolver::iterator it ) { if (e) throw(sys::system_error(e, "handle_resolve")); resolve_it = it; } void handle_connect ( const sys::error_code& e ) { if (e) throw(sys::system_error(e, "handle_connect")); } void handle_async_read_some ( const sys::error_code& e , std::size_t bytes_transferred ) { std::cerr << "handle_async_read_some" << std::endl; if (e) { if (aio::error::eof == e) received_count = 0; else throw(sys::system_error(e, "handle_async_read_some")); } else received_count = bytes_transferred; } void handle_cancel() { std::cerr << "handle_cancel" << std::endl; pres->cancel(); // on windows the following should call CancelIO causing // handle_async_read_some to return with an error. // But it does not :-( psock->cancel(); } void cancel() { std::cerr << "cancel" << std::endl; // delegate to main thread pio->post(handle_cancel); } int main() { boost::thread ctrl(ctrl_poll); signal(SIGINT, sig_handler); char c; aio::io_service io; ip::tcp::resolver res(io); ip::tcp::socket sock(io); pio = &io; pres = &res; psock = &sock; // connect the cancellation handler to ctrl-C shutdown_handler = cancel; try { ip::tcp::resolver::query query("localhost", "80"); res.async_resolve(query, handle_resolve); io.reset(); io.run(); sock.async_connect(*resolve_it, handle_connect); io.reset(); io.run(); sock.async_read_some(aio::buffer(&c, 1),handle_async_read_some); io.reset(); io.run(); } catch(std::runtime_error& e) { std::cerr << e.what() << std::endl; } catch(...) { std::cerr << "unknown exception" << std::endl; } std::cout << "exiting" << std::endl; ctrl_req = 0; ctrl.join(); return 0; }