Boost logo

Boost Users :

Subject: Re: [Boost-users] More problems with boost::asio and async_read
From: Allan Nielsen (a_at_[hidden])
Date: 2011-08-08 16:01:29


Hi Again

I have now adjusted it to not take references to any temporary objects:

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/optional.hpp>
#include <boost/system/error_code.hpp>

class ReadWithTimeout {
    public:
        ReadWithTimeout() : io_stream(io_service, ::dup(STDIN_FILENO)) {
        }

        void set_result ( boost::optional<boost::system::error_code> *
a, boost::system::error_code b ) {
            if( b == 0)
                a->reset( b );
        }

        void receive(){
            // clear pending flags
            timer_result = boost::optional<boost::system::error_code>();
            read_result = boost::optional<boost::system::error_code>();

            boost::asio::deadline_timer timer( io_service );
            timer.expires_from_now( boost::posix_time::seconds(5) );
            timer.async_wait(
boost::bind(&ReadWithTimeout::set_result, this, &timer_result, _1) );

            boost::asio::async_read(
                    io_stream,
                    buf,
                    boost::asio::transfer_at_least(1),
                    boost::bind(&ReadWithTimeout::set_result, this,
&read_result, _1));
            boost::system::error_code ec;

            while(1) {
                io_service.reset();
                io_service.poll_one(ec);

                if ( read_result ) {
                    timer.cancel();
                    return;

                } else if ( timer_result )
                    throw std::runtime_error("Timeout");
            }
        }

        std::string receive(size_t size){
            while( buf.size() < size )
                receive();

            std::string s(boost::asio::buffer_cast<const char *
>(buf.data()), boost::asio::buffer_cast<const char * >(buf.data()) +
size);
            buf.consume(size);

            return s;
        }

    private:
        boost::asio::io_service io_service;
        boost::asio::posix::stream_descriptor io_stream;

        boost::asio::streambuf buf;
        boost::optional<boost::system::error_code> timer_result;
        boost::optional<boost::system::error_code> read_result;
};

int main(int argc, const char *argv[]) {
    ReadWithTimeout xx;

    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 {
            std::cout << "out> " << xx.receive(5);

        } catch (const std::exception & e) {
            std::cout << e.what() << std::endl;
        }
    }

    return 0;
}

But, I'm not sure whether this is a good idea, because I keep on
creating new async_read (things, objects??) how are they being cleaned
up?

--
Allan

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