summaryrefslogtreecommitdiff
path: root/cpp/src/qpid
diff options
context:
space:
mode:
authorTed Ross <tross@apache.org>2011-07-12 18:29:22 +0000
committerTed Ross <tross@apache.org>2011-07-12 18:29:22 +0000
commit8a0caaf73b8f0559eef1272cab4a4a88246a7259 (patch)
treebd7a55221e8ef11f2d95676f1fe2d860cd8cff9c /cpp/src/qpid
parent90c372a1ba7a3f79ffeb362eba5bc06bd90d3fbf (diff)
downloadqpid-python-8a0caaf73b8f0559eef1272cab4a4a88246a7259.tar.gz
QPID-3352 - Federation bridge doesn't recover from session errors
Applied patch from Jason Dillaman git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1145706 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid')
-rw-r--r--cpp/src/qpid/amqp_0_10/SessionHandler.cpp5
-rw-r--r--cpp/src/qpid/broker/Bridge.cpp6
-rw-r--r--cpp/src/qpid/broker/Bridge.h2
-rw-r--r--cpp/src/qpid/broker/Link.cpp15
4 files changed, 25 insertions, 3 deletions
diff --git a/cpp/src/qpid/amqp_0_10/SessionHandler.cpp b/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
index 97281a8d8c..578598a146 100644
--- a/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
+++ b/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
@@ -188,9 +188,10 @@ void SessionHandler::detach(const std::string& name) {
void SessionHandler::detached(const std::string& name, uint8_t code) {
CHECK_NAME(name, "session.detached");
awaitingDetached = false;
- if (code != session::DETACH_CODE_NORMAL)
+ if (code != session::DETACH_CODE_NORMAL) {
+ sendReady = receiveReady = false;
channelException(convert(code), "session.detached from peer.");
- else {
+ } else {
handleDetach();
}
}
diff --git a/cpp/src/qpid/broker/Bridge.cpp b/cpp/src/qpid/broker/Bridge.cpp
index 7fbbf4e2c4..c709606c17 100644
--- a/cpp/src/qpid/broker/Bridge.cpp
+++ b/cpp/src/qpid/broker/Bridge.cpp
@@ -164,6 +164,12 @@ void Bridge::destroy()
listener(this);
}
+bool Bridge::isSessionReady() const
+{
+ SessionHandler& sessionHandler = conn->getChannel(id);
+ return sessionHandler.ready();
+}
+
void Bridge::setPersistenceId(uint64_t pId) const
{
persistenceId = pId;
diff --git a/cpp/src/qpid/broker/Bridge.h b/cpp/src/qpid/broker/Bridge.h
index a846254c57..8b4559a871 100644
--- a/cpp/src/qpid/broker/Bridge.h
+++ b/cpp/src/qpid/broker/Bridge.h
@@ -59,6 +59,8 @@ public:
void destroy();
bool isDurable() { return args.i_durable; }
+ bool isSessionReady() const;
+
management::ManagementObject* GetManagementObject() const;
management::Manageable::status_t ManagementMethod(uint32_t methodId,
management::Args& args,
diff --git a/cpp/src/qpid/broker/Link.cpp b/cpp/src/qpid/broker/Link.cpp
index 9ab4379a69..8010bf43e7 100644
--- a/cpp/src/qpid/broker/Link.cpp
+++ b/cpp/src/qpid/broker/Link.cpp
@@ -248,6 +248,19 @@ void Link::ioThreadProcessing()
return;
QPID_LOG(debug, "Link::ioThreadProcessing()");
+ // check for bridge session errors and recover
+ if (!active.empty()) {
+ Bridges::iterator removed = std::remove_if(
+ active.begin(), active.end(), !boost::bind(&Bridge::isSessionReady, _1));
+ for (Bridges::iterator i = removed; i != active.end(); ++i) {
+ Bridge::shared_ptr bridge = *i;
+ bridge->closed();
+ bridge->cancel(*connection);
+ created.push_back(bridge);
+ }
+ active.erase(removed, active.end());
+ }
+
//process any pending creates and/or cancellations
if (!created.empty()) {
for (Bridges::iterator i = created.begin(); i != created.end(); ++i) {
@@ -296,7 +309,7 @@ void Link::maintenanceVisit ()
}
}
}
- else if (state == STATE_OPERATIONAL && (!created.empty() || !cancellations.empty()) && connection != 0)
+ else if (state == STATE_OPERATIONAL && (!active.empty() || !created.empty() || !cancellations.empty()) && connection != 0)
connection->requestIOProcessing (boost::bind(&Link::ioThreadProcessing, this));
}