My Program acts as a server to which a client can connect. Once a client connected, he will get updates from the server every ~5 seconds. This is the write
-function that is called every 5 seconds to send the new data to the client:
void NIUserSession::write(std::string &message_orig)
{
std::cout << "Writing message" << std::endl;
std::shared_ptr<std::string> message = std::make_shared<std::string>( message_orig );
message->append("<EOF>");
boost::system::error_code ec;
boost::asio::async_write(this->socket_, boost::asio::buffer(*message),
boost::asio::transfer_all(), boost::bind(&NIUserSession::writeHandler,
this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred(),
message
));
}
void NIUserSession::writeHandler(const boost::system::error_code &error, std::size_t bytes_transferred, std::shared_ptr<std::string> message)
{
std::cout << "Write Handler" << std::endl;
if(error)
{
std::cout << "Write handler error: " << error.message() << std::endl;
this->disconnect();
}
}
void NIUserSession::disconnect()
{
std::cout << "Disconnecting client, cancling all write and read operations." << std::endl;
this->socket_.lowest_layer().cancel();
delete this;
}
If there is an error in the write operations the connection between the server and the client gets closed and all async operations are cancled (this->socket_.lowest_layer().cancel();
).
The problem is that if the connection times out, writeHandler
will not be called immediately. Instead, the write operations "stack up" until the first one reaches writeHandler
.
This should be the normal output of the program:
Writing message
Write Handler
... Other stuff ...
... Other stuff ...
Writing message
Write Handler
If the connections times out, this is what happens:
Writing message
Write Handler
Write handler error: Connection timed out
Disconnecting client, cancling all write and read operations.
Write Handler
Write Handler
Write Handler
Write Handler
Write Handler
Write Handler
Write Handler
Write Handler
Write Handler
Write Handler
Write Handler
Segmentation fault
At the end, a segmentation fault rises. I think this is because disconnect
is called while other async operations are still on their way.
I thought I could avoid it by using this->socket_.lowest_layer().cancel();
directly after the first async operation fails, but it doesn't work.
How can I avoid a segmentation fault?