summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorGordon Sim <gsim@apache.org>2010-08-20 09:29:31 +0000
committerGordon Sim <gsim@apache.org>2010-08-20 09:29:31 +0000
commit91a4eda9bfa588f1d017c218ac2bcc9713338ef2 (patch)
treeac6e1293404f93a7b14b88fc5eab3fa4a51e033e /cpp
parent6217978d75d7c80f3069e5c39a85f32d744f70e1 (diff)
downloadqpid-python-91a4eda9bfa588f1d017c218ac2bcc9713338ef2.tar.gz
QPID-2817: on close, wait for at most the heartbeat interval (if specified) for close-ok response from broker
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@987429 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/qpid/client/ConnectionHandler.cpp9
-rw-r--r--cpp/src/qpid/client/StateManager.cpp20
-rw-r--r--cpp/src/qpid/client/StateManager.h2
3 files changed, 30 insertions, 1 deletions
diff --git a/cpp/src/qpid/client/ConnectionHandler.cpp b/cpp/src/qpid/client/ConnectionHandler.cpp
index ba15e635cf..e615878703 100644
--- a/cpp/src/qpid/client/ConnectionHandler.cpp
+++ b/cpp/src/qpid/client/ConnectionHandler.cpp
@@ -157,7 +157,14 @@ void ConnectionHandler::close()
case OPEN:
if (setState(CLOSING, OPEN)) {
proxy.close(200, OK);
- waitFor(FINISHED);//FINISHED = CLOSED or FAILED
+ if (ConnectionSettings::heartbeat) {
+ //heartbeat timer is turned off at this stage, so don't wait indefinately
+ if (!waitFor(FINISHED, qpid::sys::Duration(ConnectionSettings::heartbeat * qpid::sys::TIME_SEC))) {
+ QPID_LOG(warning, "Connection close timed out");
+ }
+ } else {
+ waitFor(FINISHED);//FINISHED = CLOSED or FAILED
+ }
}
//else, state was changed from open after we checked, can only
//change to failed or closed, so nothing to do
diff --git a/cpp/src/qpid/client/StateManager.cpp b/cpp/src/qpid/client/StateManager.cpp
index 5462e0fed4..839d92abdc 100644
--- a/cpp/src/qpid/client/StateManager.cpp
+++ b/cpp/src/qpid/client/StateManager.cpp
@@ -52,6 +52,26 @@ void StateManager::waitFor(std::set<int> desired)
}
}
+bool StateManager::waitFor(int desired, qpid::sys::Duration timeout)
+{
+ AbsTime end(now(), timeout);
+ Monitor::ScopedLock l(stateLock);
+ while (state != desired && now() < end) {
+ stateLock.wait(end);
+ }
+ return state == desired;
+}
+
+bool StateManager::waitFor(std::set<int> desired, qpid::sys::Duration timeout)
+{
+ AbsTime end(now(), timeout);
+ Monitor::ScopedLock l(stateLock);
+ while (desired.find(state) == desired.end() && now() < end) {
+ stateLock.wait(end);
+ }
+ return desired.find(state) != desired.end();
+}
+
void StateManager::setState(int s)
{
diff --git a/cpp/src/qpid/client/StateManager.h b/cpp/src/qpid/client/StateManager.h
index 3c8412dfa7..f06dbc493c 100644
--- a/cpp/src/qpid/client/StateManager.h
+++ b/cpp/src/qpid/client/StateManager.h
@@ -41,6 +41,8 @@ public:
void waitForStateChange(int current);
void waitFor(std::set<int> states);
void waitFor(int state);
+ bool waitFor(std::set<int> states, qpid::sys::Duration);
+ bool waitFor(int state, qpid::sys::Duration);
};
}}