forgive me. I read "a synchronous call" as "asynchronous call". Of course the correct way to "cancel" a sync call in linux is to raise a signal, which should cause the socket's read to return with EINTR. But before I realised my mistake, I wrote this little test to prove that async calls are canclled :) Maybe someone will find it useful... #include <cstdlib> #include <sys/types.h> #include <sys/wait.h> #include <iostream> #include <string> #include <boost/asio.hpp> using namespace std::literals; namespace asio = boost::asio; using protocol = asio::ip::tcp; void server(protocol::acceptor& acceptor, int child_pid) { acceptor.listen(); auto& executor = acceptor.get_io_context(); auto sock = protocol::socket(executor); auto timer = asio::system_timer(executor); acceptor.accept(sock); auto read_handler = [](auto ec, auto...) { if (ec) std::cerr << "read handler error: " << ec.message(); else std::cerr << "strange - we expected an error"; }; auto timer_handler = [&](auto ec) { if (not ec) { sock.cancel(); } }; sock.async_read_some(asio::null_buffers(), read_handler); timer.expires_after(1s); timer.async_wait(timer_handler); executor.run(); auto data = "foo"s; sock.write_some(asio::buffer(data)); int status = 0; waitpid(child_pid, & status, 0); } void client(asio::io_context& executor, protocol::endpoint server_endpoint) { protocol::socket sock(executor); sock.connect(server_endpoint); auto on_read = [](auto, auto) {}; sock.async_read_some(asio::null_buffers(), on_read); executor.run(); } int main() { auto executor = asio::io_context(); auto acceptor = protocol::acceptor(executor); acceptor.open(protocol::v4()); acceptor.bind(protocol::endpoint(protocol::v4(), 0)); auto server_endpoint = acceptor.local_endpoint(); executor.notify_fork(asio::io_context::fork_prepare); int child_pid = fork(); if (child_pid < 0) { std::cerr << "fork failed" << std::endl; std::exit(100); } else if (child_pid > 0) { executor.notify_fork(asio::io_context::fork_parent); server(acceptor,child_pid); } else { executor.notify_fork(asio::io_context::fork_child); client(executor, server_endpoint); } return 0; } expected output:
*read handler error: Operation canceled*
On 23 March 2018 at 08:44, Thomas Quarendon via Boost-users < boost-users@lists.boost.org> wrote:
This seems unlikely. I have been using asio in production code on Linux for 4 years. Can you post a mcve so I can test? Yes, the code I started this thread with: https://gist.github.com/tomq42/331b8d48110c5025e0fce93e689bd5a3
I don't think this is a surprise. As far as I understand it, "cancel" isn't expected to cancel a *synchronous* read from the socket. It's more of a surprise to me that calling close on the socket doesn't have the effect of causing the read to return with an error. Both of these things work on Windows, and I started out on Windows, so the code was all fine there. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users