Boost.Asio: Async operations timeout

Bobface

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 disconnectis 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?

Rudolfs Bundulis

Well, you should not delete this when cancelling the operations since the callbacks for the pending I/O operations will still be invoked and then accessing this leads to undefined behavior. There are multiple ways to tackle this:

  1. Don't write data until you actually know that previous data has been written. You could queue the std::string instances passed to NIUserSession::write in case an outstanding write is still pending and then actually write them in the handler when the outstanding write operation completes. That way you will not have multiple I/O operations in flight.
  2. Inherit from std::enable_shared_from_this and pass shared_from_this() instead of this to the async_write call (this is what the Boost asynchronous TCP daytime server example does). That way pending I/O operations will keep a reference to your class and the destructor will be called if all of them complete.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Generic way to timeout async operations in boost::asio

From Dev

Boost.Asio: Async operations timeout

From Dev

Boost ASIO - What is async

From Dev

Waiting with timeout on boost::asio::async_connect fails (std::future::wait_for)

From Dev

Waiting with timeout on boost::asio::async_connect fails (std::future::wait_for)

From Dev

asio - Wait for async operations to finish

From Dev

Boost::Asio Async write failed

From Dev

Boost asio TCP async server not async?

From Dev

Boost asio for multiple asynchronous network client operations

From Dev

asio async operations aren't processed

From Dev

boost asio async udp server - poor performance

From Dev

Boost asio trouble with async_read_until

From Dev

Boost asio async operation bad file descriptor

From Dev

boost asio async udp server - poor performance

From Dev

Boost::asio async_write_some vs async_send

From Dev

Boost asio async_read_until followed by async_read

From Dev

Long-running / blocking operations in boost asio handlers

From Dev

boost::asio::async_read 100% CPU usage on simple example

From Dev

Boost asio async_read_some returning small amount of data

From Dev

boost::asio::async_write and buffers over 65536 bytes

From Dev

"two-step" async_read with boost asio

From Dev

boost::asio::async_read return end of file error on newline

From Dev

What is the use of boost::asio::async_write function

From Dev

boost asio multiple async_send on udp socket

From Dev

boost asio ssl async_shutdown always finishes with an error?

From Dev

Boost Asio connect_async never call hander

From Dev

How to use lambda to for boost asio async completion handler

From Dev

Boost asio - async reading established number of chars from stdin

From Dev

boost::asio::deadline_timer::async_wait not firing callback

Related Related

  1. 1

    Generic way to timeout async operations in boost::asio

  2. 2

    Boost.Asio: Async operations timeout

  3. 3

    Boost ASIO - What is async

  4. 4

    Waiting with timeout on boost::asio::async_connect fails (std::future::wait_for)

  5. 5

    Waiting with timeout on boost::asio::async_connect fails (std::future::wait_for)

  6. 6

    asio - Wait for async operations to finish

  7. 7

    Boost::Asio Async write failed

  8. 8

    Boost asio TCP async server not async?

  9. 9

    Boost asio for multiple asynchronous network client operations

  10. 10

    asio async operations aren't processed

  11. 11

    boost asio async udp server - poor performance

  12. 12

    Boost asio trouble with async_read_until

  13. 13

    Boost asio async operation bad file descriptor

  14. 14

    boost asio async udp server - poor performance

  15. 15

    Boost::asio async_write_some vs async_send

  16. 16

    Boost asio async_read_until followed by async_read

  17. 17

    Long-running / blocking operations in boost asio handlers

  18. 18

    boost::asio::async_read 100% CPU usage on simple example

  19. 19

    Boost asio async_read_some returning small amount of data

  20. 20

    boost::asio::async_write and buffers over 65536 bytes

  21. 21

    "two-step" async_read with boost asio

  22. 22

    boost::asio::async_read return end of file error on newline

  23. 23

    What is the use of boost::asio::async_write function

  24. 24

    boost asio multiple async_send on udp socket

  25. 25

    boost asio ssl async_shutdown always finishes with an error?

  26. 26

    Boost Asio connect_async never call hander

  27. 27

    How to use lambda to for boost asio async completion handler

  28. 28

    Boost asio - async reading established number of chars from stdin

  29. 29

    boost::asio::deadline_timer::async_wait not firing callback

HotTag

Archive