[asio] setting a timeout on blocking write's/read's

Hi Guys, I'm currently working on a type-safe memcache client library using Boost.Asio (Friendster has plans on open sourcing it, but we're continuing developing in house before doing so, to make it more feature-full). Having said this, it involves having to write the network layer stuff and I've chosen to use Boost.Asio. We've been fairly successful so far, we currently have a working library (header only) already using Boost.Serialization + Boost.Spirit + Boost.Asio + Many Boost C++ Libraries and we're looking at putting a few more features in. One of these features is the ability to make a request to the server, and time-out after a short period of time (configurable, defaults to 1 second). For a myriad of reasons, we're using blocking API calls (boost::asio::read_until and boost::asio::write) but these API calls don't seem to readily have a way of setting a timeout value -- one that says "try reading until either the response matches this... or throw an error after 1 second if you don't get a response from the server". Would there be a different way of going about it, aside from using asynchronous operations? Advice and insight would be most appreciated. -- Dean Michael C. Berris http://cplusplus-soup.blogspot.com/ mikhailberis AT gmail DOT com +63 928 7291459

On Tue, 24 Apr 2007 23:44:35 -0700, "Dean Michael Berris" <mikhailberis@gmail.com> said: [...]
For a myriad of reasons, we're using blocking API calls (boost::asio::read_until and boost::asio::write) but these API calls don't seem to readily have a way of setting a timeout value -- one that says "try reading until either the response matches this... or throw an error after 1 second if you don't get a response from the server".
Would there be a different way of going about it, aside from using asynchronous operations?
No, async operations would be the way to go. Something like (warning, untested code): void set_result(optional<error_code>* a, error_code b) { a->reset(b); } template <typename MutableBufferSequence> void read_with_timeout(tcp::socket& sock, const MutableBufferSequence& buffers) { optional<error_code> timer_result; deadline_timer timer(sock.io_service()); timer.expires_from_now(seconds(1)); timer.async_wait(boost::bind(set_result, &timer_result, _1)); optional<error_code> read_result; async_read(sock, buffers, boost::bind(set_result, &read_result, _1)); sock.io_service().reset(); while (sock.io_service().run_one()) { if (read_result) timer.cancel(); else if (timer_result) sock.cancel(); } if (*read_result) throw system_error(*read_result); } Cheers, Chris

On 4/26/07, Christopher Kohlhoff <chris@kohlhoff.com> wrote:
On Tue, 24 Apr 2007 23:44:35 -0700, "Dean Michael Berris" <mikhailberis@gmail.com> said: [...]
For a myriad of reasons, we're using blocking API calls (boost::asio::read_until and boost::asio::write) but these API calls don't seem to readily have a way of setting a timeout value -- one that says "try reading until either the response matches this... or throw an error after 1 second if you don't get a response from the server".
Would there be a different way of going about it, aside from using asynchronous operations?
No, async operations would be the way to go. Something like (warning, untested code):
[snipped example] And it works! Thanks Chris, it's very much appreciated. :) -- Dean Michael C. Berris http://cplusplus-soup.blogspot.com/ mikhailberis AT gmail DOT com +63 928 7291459
participants (2)
-
Christopher Kohlhoff
-
Dean Michael Berris