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
#include
#include <iostream>
#include <string>
#include
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