[svn] commit: r2632 - in /branches/trac296/src/lib/cc: session.cc session.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Aug 4 12:30:54 UTC 2010
Author: jelte
Date: Wed Aug 4 12:30:54 2010
New Revision: 2632
Log:
timeout in asio by using a call to async_read() and a deadline_timer
Modified:
branches/trac296/src/lib/cc/session.cc
branches/trac296/src/lib/cc/session.h
Modified: branches/trac296/src/lib/cc/session.cc
==============================================================================
--- branches/trac296/src/lib/cc/session.cc (original)
+++ branches/trac296/src/lib/cc/session.cc Wed Aug 4 12:30:54 2010
@@ -28,6 +28,7 @@
#include <unistd.h> // for some IPC/network system calls
#include <asio.hpp>
#include <asio/error_code.hpp>
+#include <asio/deadline_timer.hpp>
#include <asio/system_error.hpp>
#include <cstdio>
@@ -39,6 +40,7 @@
#include <boost/bind.hpp>
#include <boost/function.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <exceptions/exceptions.h>
@@ -65,7 +67,9 @@
void disconnect();
void writeData(const void* data, size_t datalen);
size_t readDataLength();
- void readData(void* data, size_t datalen);
+ // Blocking read. Will throw a SessionTimeout if the timeout value
+ // (in seconds) is thrown. If timeout is 0 it will block forever
+ void readData(void* data, size_t datalen, size_t timeout = 5);
void startRead(boost::function<void()> user_handler);
long int sequence_; // the next sequence number to use
@@ -75,6 +79,10 @@
private:
void internalRead(const asio::error_code& error,
size_t bytes_transferred);
+ // Sets the boolean pointed to by result to true, unless
+ // the given error code is operation_aborted
+ // Used as a callback for emulating sync reads with async calls
+ void setResult(bool* result, asio::error_code b);
private:
io_service& io_service_;
@@ -130,9 +138,39 @@
}
void
-SessionImpl::readData(void* data, size_t datalen) {
+SessionImpl::setResult(bool* result, asio::error_code b)
+{
+ if (b != asio::error::operation_aborted) {
+ *result = true;
+ }
+}
+
+void
+SessionImpl::readData(void* data, size_t datalen, size_t timeout) {
+ bool timer_result = false;
+ bool read_result = false;
try {
- asio::read(socket_, asio::buffer(data, datalen));
+ async_read(socket_, asio::buffer(data, datalen), asio::transfer_at_least( datalen ),
+ boost::bind(&SessionImpl::setResult, this, &read_result, _1));
+ asio::deadline_timer timer(socket_.io_service());
+
+ if (timeout != 0) {
+ timer.expires_from_now(boost::posix_time::seconds(timeout));
+ timer.async_wait(boost::bind(&SessionImpl::setResult, this, &timer_result, _1));
+ }
+
+ while (!read_result && !timer_result) {
+ socket_.io_service().run_one();
+ if (read_result) {
+ timer.cancel();
+ } else if (timer_result) {
+ socket_.cancel();
+ }
+ }
+
+ if (!read_result) {
+ isc_throw(SessionTimeout, "Timeout or error on ");
+ }
} catch (const asio::system_error& asio_ex) {
// to hide boost specific exceptions, we catch them explicitly
// and convert it to SessionError.
Modified: branches/trac296/src/lib/cc/session.h
==============================================================================
--- branches/trac296/src/lib/cc/session.h (original)
+++ branches/trac296/src/lib/cc/session.h Wed Aug 4 12:30:54 2010
@@ -37,6 +37,15 @@
class SessionError : public isc::Exception {
public:
SessionError(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+ };
+
+ /// \brief A standard Exception class that is thrown when a
+ /// blocking readData call does not read the given number of
+ /// bytes before the timeout expires
+ class SessionTimeout : public isc::Exception {
+ public:
+ SessionTimeout(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
More information about the bind10-changes
mailing list