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