Boost logo

Boost Users :

Subject: Re: [Boost-users] More problems with boost::asio and async_read
From: Igor R (boost.lists_at_[hidden])
Date: 2011-08-08 15:08:02


> Basically I'm trying to read from a input source (in this case stdin)
> with a timeout. Due to the design of the existing application where
> this have to fit is it not possible to call run on my io_service.
>
> Here is my try so far:
>
> #include <boost/asio.hpp>
> #include <boost/bind.hpp>
> #include <boost/optional.hpp>
>
> using namespace std;
>
> void set_result( boost::optional<boost::system::error_code> * a,
> boost::system::error_code b ) {
>    if( b == 0)
>        a->reset( b );
> }
>
> void receive(boost::asio::io_service & io,
> boost::asio::posix::stream_descriptor & stream, boost::asio::streambuf
> & result){
>    boost::optional<boost::system::error_code> timer_result;
>    boost::optional<boost::system::error_code> read_result;
>
>    boost::asio::deadline_timer timer( io );
>    timer.expires_from_now( boost::posix_time::milliseconds(5000) );
> // allow up to 50ms of timeout for every char
>    timer.async_wait( boost::bind(&set_result, &timer_result, _1) );
>
>    boost::asio::async_read(
>            stream,
>            result,
>            boost::asio::transfer_at_least(1),
>            boost::bind( &set_result, &read_result, _1 ));
>    boost::system::error_code ec;
>
>    while(1) {
>        io.reset();
>        io.poll_one(ec);
>
>        if ( read_result ) {
>            timer.cancel();
>            return;
>
>        } else if ( timer_result )
>            throw std::runtime_error("timeout");
>    }
> }
>
> void receive(boost::asio::io_service & io,
> boost::asio::posix::stream_descriptor & stream, size_t size,
> boost::asio::streambuf & result){
>    while( result.size() < size )
>        receive(io, stream, result);
> }
>
> int main(int argc, const char *argv[])
> {
>    boost::asio::io_service io;
>    boost::asio::posix::stream_descriptor in(io, ::dup(STDIN_FILENO));
>
>    for(int i = 0; i < 5; i++){
>        std::cout << i << " Type in 4 chareters and press enter" <<
> std::endl << std::endl;
>        std::cout << "in> ";
>        std::cout.flush();
>        try {
>            boost::asio::streambuf buf;
>            receive(io, in, 5, buf);
>            std::cout << "out> ";
>            std::copy(boost::asio::buffer_cast<const char
> *>(buf.data()), boost::asio::buffer_cast<const char *>(buf.data()) +
> buf.size(), ostream_iterator<char>(std::cout));
>
>        } catch (const std::exception & e) {
>            std::cout << e.what() << endl;
>        }
>    }
>
>    return 0;
> }

You bind your completion handlers to addresses of local objects. I
admit I didn't investigate your code in depth, but at a glance - I'm
not sure all these locals always outlive the appropriate functors...


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net