diff options
author | Gordon Sim <gsim@apache.org> | 2009-06-17 17:13:13 +0000 |
---|---|---|
committer | Gordon Sim <gsim@apache.org> | 2009-06-17 17:13:13 +0000 |
commit | 9e3b98bffa42574cf09682e50867b72a8b365b5b (patch) | |
tree | bece525410bbab33c9eb4f7c7fa6bcd2dbeb1ace /qpid/cpp/src | |
parent | e04f58117006e8f0b7edcb0bcd00a33c6f6b5755 (diff) | |
download | qpid-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.cpp | 54 | ||||
-rw-r--r-- | qpid/cpp/src/qpid/broker/Connection.h | 3 |
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; |