summaryrefslogtreecommitdiff
path: root/qpid/cpp/src
diff options
context:
space:
mode:
authorGordon Sim <gsim@apache.org>2009-06-17 17:13:13 +0000
committerGordon Sim <gsim@apache.org>2009-06-17 17:13:13 +0000
commit9e3b98bffa42574cf09682e50867b72a8b365b5b (patch)
treebece525410bbab33c9eb4f7c7fa6bcd2dbeb1ace /qpid/cpp/src
parente04f58117006e8f0b7edcb0bcd00a33c6f6b5755 (diff)
downloadqpid-python-9e3b98bffa42574cf09682e50867b72a8b365b5b.tar.gz
Ensure that the ConnectionTimeoutTask does not block other tasks (e.g. ConnectionHeartbeatTask) by having the timeout changed after it has been submitted.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@785733 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src')
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.cpp54
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.h3
2 files changed, 35 insertions, 22 deletions
diff --git a/qpid/cpp/src/qpid/broker/Connection.cpp b/qpid/cpp/src/qpid/broker/Connection.cpp
index a57b59ae2c..fb087181a3 100644
--- a/qpid/cpp/src/qpid/broker/Connection.cpp
+++ b/qpid/cpp/src/qpid/broker/Connection.cpp
@@ -48,6 +48,38 @@ namespace _qmf = qmf::org::apache::qpid::broker;
namespace qpid {
namespace broker {
+struct ConnectionTimeoutTask : public TimerTask {
+ Timer& timer;
+ Connection& connection;
+ AbsTime expires;
+
+ ConnectionTimeoutTask(uint16_t hb, Timer& t, Connection& c) :
+ TimerTask(Duration(hb*2*TIME_SEC)),
+ timer(t),
+ connection(c),
+ expires(AbsTime::now(), duration)
+ {}
+
+ void touch()
+ {
+ expires = AbsTime(AbsTime::now(), duration);
+ }
+
+ void fire() {
+ // This is the best we can currently do to avoid a destruction/fire race
+ if (isCancelled()) return;
+ if (expires < AbsTime::now()) {
+ // If we get here then we've not received any traffic in the timeout period
+ // Schedule closing the connection for the io thread
+ QPID_LOG(error, "Connection timed out: closing");
+ connection.abort();
+ } else {
+ reset();
+ timer.add(this);
+ }
+ }
+};
+
Connection::Connection(ConnectionOutputHandler* out_, Broker& broker_, const std::string& mgmtId_, bool isLink_, uint64_t objectId) :
ConnectionState(out_, broker_),
adapter(*this, isLink_),
@@ -325,26 +357,6 @@ struct ConnectionHeartbeatTask : public TimerTask {
}
};
-struct ConnectionTimeoutTask : public TimerTask {
- Timer& timer;
- Connection& connection;
- ConnectionTimeoutTask(uint16_t hb, Timer& t, Connection& c) :
- TimerTask(Duration(hb*2*TIME_SEC)),
- timer(t),
- connection(c)
- {}
-
- void fire() {
- // This is the best we can currently do to avoid a destruction/fire race
- if (!isCancelled()) {
- // If we get here then we've not received any traffic in the timeout period
- // Schedule closing the connection for the io thread
- QPID_LOG(error, "Connection timed out: closing");
- connection.abort();
- }
- }
-};
-
void Connection::abort()
{
out.abort();
@@ -364,7 +376,7 @@ void Connection::setHeartbeatInterval(uint16_t heartbeat)
void Connection::restartTimeout()
{
if (timeoutTimer)
- timeoutTimer->reset();
+ timeoutTimer->touch();
}
}}
diff --git a/qpid/cpp/src/qpid/broker/Connection.h b/qpid/cpp/src/qpid/broker/Connection.h
index db18c48d82..540f64a8ed 100644
--- a/qpid/cpp/src/qpid/broker/Connection.h
+++ b/qpid/cpp/src/qpid/broker/Connection.h
@@ -60,6 +60,7 @@ namespace broker {
class LinkRegistry;
class SecureConnection;
+struct ConnectionTimeoutTask;
class Connection : public sys::ConnectionInputHandler,
public ConnectionState,
@@ -153,7 +154,7 @@ class Connection : public sys::ConnectionInputHandler,
management::ManagementAgent* agent;
Timer& timer;
boost::intrusive_ptr<TimerTask> heartbeatTimer;
- boost::intrusive_ptr<TimerTask> timeoutTimer;
+ boost::intrusive_ptr<ConnectionTimeoutTask> timeoutTimer;
ErrorListener* errorListener;
bool shadow;