summaryrefslogtreecommitdiff
path: root/qpid/cpp
diff options
context:
space:
mode:
authorGordon Sim <gsim@apache.org>2014-06-03 19:04:45 +0000
committerGordon Sim <gsim@apache.org>2014-06-03 19:04:45 +0000
commitf3599d8e82635c80242e2c7b6047f2e20d4b9735 (patch)
tree14b06e5ca6511532886b6991db4e5829741224bc /qpid/cpp
parentd45b5f6510da0e0d0f925bf8e9e443bd7d50bf3c (diff)
downloadqpid-python-f3599d8e82635c80242e2c7b6047f2e20d4b9735.tar.gz
QPID-5793: prevent leak due to concurrent bind and delete
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1599766 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp')
-rw-r--r--qpid/cpp/src/qpid/broker/Queue.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/qpid/cpp/src/qpid/broker/Queue.cpp b/qpid/cpp/src/qpid/broker/Queue.cpp
index e91123eb6a..dcd62e42aa 100644
--- a/qpid/cpp/src/qpid/broker/Queue.cpp
+++ b/qpid/cpp/src/qpid/broker/Queue.cpp
@@ -1127,10 +1127,10 @@ void Queue::destroyed()
store->destroy(*this);
store = 0;//ensure we make no more calls to the store for this queue
}
- if (autoDeleteTask) autoDeleteTask = boost::intrusive_ptr<TimerTask>();
notifyDeleted();
{
Mutex::ScopedLock l(messageLock);
+ if (autoDeleteTask) autoDeleteTask = boost::intrusive_ptr<TimerTask>();
observers.destroy(l);
}
if (mgmtObject != 0) {
@@ -1278,7 +1278,17 @@ void Queue::scheduleAutoDelete()
void Queue::tryAutoDelete()
{
- if (broker->getQueues().destroyIf(name, boost::bind(boost::mem_fn(&Queue::canAutoDelete), shared_from_this()))) {
+ bool proceed(false);
+ {
+ Mutex::ScopedLock locker(messageLock);
+ if (!deleted && checkAutoDelete(locker)) {
+ proceed = true;
+ deleted = true;
+ }
+ }
+
+ if (proceed) {
+ broker->getQueues().destroy(name);
if (broker->getAcl())
broker->getAcl()->recordDestroyQueue(name);
@@ -1536,7 +1546,7 @@ void Queue::flush()
bool Queue::bind(boost::shared_ptr<Exchange> exchange, const std::string& key,
const qpid::framing::FieldTable& arguments)
{
- if (exchange->bind(shared_from_this(), key, &arguments)) {
+ if (!isDeleted() && exchange->bind(shared_from_this(), key, &arguments)) {
bound(exchange->getName(), key, arguments);
if (exchange->isDurable() && isDurable()) {
store->bind(*exchange, *this, key, arguments);