Documentation error: async_write() "always returns immediately" [false?]
Brought to you by:
chris_kohlhoff
The program shown below was compiled using GNU g++ v4.4.3:
$ g++ -o main main.cc -lboost_system # Boost 1-55-0
The program prints the string
@The quick brown fox jumps over the lazy dog.
one character at a time and, in doing so, it clearly demonstrates that both:
before the call to async_write() returns. The evidence can be found on the 1st and 2nd lines of the program's output:
$ ./main
- CompletionCheck::operator()(error=system:0, bytes transferred=0)
@ - async_write() has returned
The quick brown fox jumps over the lazy dog.
handler() - completion handler called
which shows:
The rest of the string is printed only after invoking the io_service's run() method.
So: Is the async_write() documentation incorrect when it states that the call ** "always returns immediately" ?**
I would have expected nothing to happen until calling the run() method.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <vector>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
static void handler(const boost::system::error_code& error, std::size_t bytes_transferred)
{
std::cerr << "handler() - completion handler called" << std::endl;
}
class CompletionCheck
{
public:
CompletionCheck(std::vector<boost::asio::const_buffer>& buffers)
: count_(boost::asio::buffer_size(buffers))
{
}
size_t operator()(const boost::system::error_code& error, std::size_t bytes_transferred)
{
if (bytes_transferred == 0)
{
std::cerr << " - CompletionCheck::operator()(error=" << error
<< ", bytes transferred=" << bytes_transferred << ")" << std::endl;
}
if (count_)
{
--count_;
return 1;
}
return 0;
}
private:
size_t count_;
};
int main(int argc, char * argv[])
{
boost::asio::io_service iosvc;
std::vector<boost::asio::const_buffer> vec;
vec.push_back(boost::asio::buffer("@The"));
vec.push_back(boost::asio::buffer(" quick"));
vec.push_back(boost::asio::buffer(" brown"));
vec.push_back(boost::asio::buffer(" fox"));
vec.push_back(boost::asio::buffer(" jumps"));
vec.push_back(boost::asio::buffer(" over"));
vec.push_back(boost::asio::buffer(" the"));
vec.push_back(boost::asio::buffer(" lazy"));
vec.push_back(boost::asio::buffer(" dog.\n"));
boost::asio::posix::stream_descriptor ios(iosvc);
ios.assign(::open("/dev/tty", O_WRONLY|O_ASYNC));
CompletionCheck check(vec);
boost::asio::async_write(ios, vec, check, boost::bind(&handler, _1, _2));
std::cerr << " - async_write() has returned" << std::endl;
iosvc.run();
return 0;
}