Boost async_write problem

12,790

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.

Share:
12,790
hansen
Author by

hansen

Updated on June 15, 2022

Comments

  • hansen
    hansen almost 2 years

    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 ...

  • Sam Miller
    Sam Miller about 13 years
    @hansen I've added an example.
  • Michael Mueller
    Michael Mueller almost 9 years
    Just FYI: the code snippet OP provided is mostly correct. The only thing that it doesn't account for is that it takes longer to send data out of the port than it does to call async_write. You're queuing up write completion events into the io_service queue faster than it can complete them. The documentation says that you can't call more than one write operation on the same object from more than one thread at a time.