|
Boost : |
Subject: Re: [boost] async_read SEGFAULT
From: Richard Hodges (hodges.r_at_[hidden])
Date: 2019-01-06 07:27:13
Once you initiate an async operation against a memory buffer, the contents
of that buffer are *undefined* from the moment you have called the
async_XXX function until the moment control is resumed in the handler
function you submitted.
For example, imagine an object, even one protected by a strand...
void myobject::initiate_read()
{
// notes:
// making completion handlers mutable allows asio to move them
internally, which is an optimisation
// it also allows them to carry move-only objects as part of their state
auto handler = [self = this->shared_from_this()]
(auto ec, auto bytes_transferred) mutable
{
// You are now in the the completion handler.
// you may now read from self->mybuffer
self->handle_read(ec, bytes_transferred);
};
// initiate async function.
asio::async_read_until(mysocket,
mybuffer, // in this case we're using a
streambuf but the principles are the same
'\n', // if we used
asio::buffer(some-container) as the buffer object
asio::bind_executor(mystrand, //
because we're using a strand, we must bind the handler
std::move(handler)); // to
the strand to ensure that no two handlers run simultaneously
// mybuffer is now in an undefined state.
// it is inappropriate to use it in any way from now on
// the place to read it is in the method myobject::handle_read
}
void myobject::handle_read(system::error_code ec, std::size_t
bytes_transferred)
{
// for composed operations like async_read_until it is possible that some
data is read *and* that we get
// an error indicated.
// however, for now we'll ignore that complication
if (ec == system::error_code()) // the correct way to check for 'no
error'
{
// it's safe to manipulate the buffer here as there are no async
operations
// in flight that touch it.
std::string s;
auto is = std::istream(&mybuffer);
std::getline(is, s);
do_something(s);
// NOW re-initiate the async read
initiate_read();
}
else
{
// do error handling here and don't reinitiate read
}
}
On Sun, 6 Jan 2019 at 07:50, hh h via Boost <boost_at_[hidden]> wrote:
> If all async_read and async_write need a static life time buffer, do I
> need to worry about potential buffer overwritten before the buffer
> process is completed?
>
> Take an example, if a lift_time_buffer is a static buffer for
> async_read, when the socket gets the data, it fills data into the
> buffer, then the buffer is passed to higher level applications for
> processing, before the buffer process is completed, the socket
> receives more data and write the data to the buffer again since it is
> async process, that will certainly result data corruption. The same
> story could apply for async_write if one static life time buffer to
> async_write.
>
> Is that thought overstated? Or it needs a real concern?
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
-- Richard Hodges hodges.r_at_[hidden] office: +442032898513 home: +376841522 mobile: +376380212 (this will be *expensive* outside Andorra!) skype: madmongo facebook: hodges.r
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk