Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::async_write causing data corrupted

I'm currently using boost::async_write to send large sized buffer(about 50KB) once a time. The result is I'm receiving for about one corrupted buffer in every 20 buffers on the server side.

My code is like this. Error handling and other details are omitted:

bool socket_available = true;
const_buffer *buffer;

// will be called frequently in a while loop in thread A
void send_buffer()
{
    scope_lock l(mutex);
    if (!socket_available) return;

    socket_available = false;
    buffer = get_buffer_for_send();   // The size is about 50KB
    boost::asio::async_write(
        socket, buffer,
        boost::bind(handle_write_request, boost::asio::placeholders::error)
    );
}

// will be called in thread B which runs io_service::run
void handle_write_request(const boost::system::error_code& error_code)
{
    scope_lock l(mutex);
    socket_available = true;
    free_buffer(buffer);
}

I believe I'm using async_write correctly because I only call async_write one time after the handler is called(http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/async_write/overload1.html). However the data still seems interleaved during sending.

I know the common way of doing such thing is to put the async_write in the handler so they will both be called in one thread. And when I'm doing this, no data corruption happens again. So I'm just here wondering why the above code won't work as expected.

Thanks for your time and advice. BTW, I'm using boost 1.54.0 under win 7.

like image 339
user2028206 Avatar asked Nov 27 '25 00:11

user2028206


1 Answers

Since your send is asynchronous, the buffer must remain intact for the whole duration. I can't say so from your code, for instance, using a global variable is incorrect. What would happen with 2 sends at the same time? Also, get_buffer_for_send() is not shown, it could contain problems too.

like image 149
Codeguard Avatar answered Nov 28 '25 17:11

Codeguard