|
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