Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost async_write problem

i'll show some piece of code ;

void wh(const boost::system::error_code& ec,
        std::size_t bytes_transferred)
{
    std::cout << "test";
}

int main(int argc, char* argv[]) 
{ 
    boost::asio::io_service pService;
    boost::asio::serial_port pSerial(pService,"COM4");

    while (true) {
        boost::asio::async_write(pSerial, boost::asio::buffer("A",1),&wh);
    }

    return 0; 
} 

when i use that code i'm getting memory leak, I found some piece of code like minicom_client tutorial even complex from that code also i'm getting memory leak on minicom_client. If i use

    boost::asio::write(pSerial, boost::asio::buffer("A",1));

instead of async_write it works well, Could you explain what's going on there , Thanks a lot ...

like image 941
hansen Avatar asked Jan 21 '23 12:01

hansen


1 Answers

You're not using async_write correctly. It is a composed operation, and it's up to the application's responsibility to ensure no other calls to async_write on pSerial are made until the write handler is invoked. The documentation summarizes this nicely

This operation is implemented in terms of zero or more calls to the stream's async_write_some function, and is known as a composed operation. The program must ensure that the stream performs no other write operations (such as async_write, the stream's async_write_some function, or any other composed operations that perform writes) until this operation completes.

emphasis added by me. To fix your application, you'll need to start additional async_write operations from within your wh() method. You'll also need to invoke io_service::run() to kick off the asynchronous event loop. If this concept is unfamiliar to you, I suggest studying the examples prior to writing your own code.

int main(int argc, char* argv[]) 
{ 
    boost::asio::io_service pService;
    boost::asio::serial_port pSerial(pService,"COM4");

    boost::asio::async_write(
        pSerial,
        boost::asio::buffer("A",1),
        boost::bind(
            &wh,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred
       );

    pService.run();

    return 0; 
} 

It's also worth noting your code as written is dangerous since the buffer will go out of scope before the handler is invoked. Typically this is accomplished by retaining the buffer as a member of an object that passes a boost::shared_ptr to the async_write handler via boost::bind. This concept is prevalent in the asio examples.

like image 62
Sam Miller Avatar answered Feb 01 '23 08:02

Sam Miller