diff options
| author | Gordon Sim <gsim@apache.org> | 2014-06-03 19:04:45 +0000 |
|---|---|---|
| committer | Gordon Sim <gsim@apache.org> | 2014-06-03 19:04:45 +0000 |
| commit | f3599d8e82635c80242e2c7b6047f2e20d4b9735 (patch) | |
| tree | 14b06e5ca6511532886b6991db4e5829741224bc /qpid/cpp | |
| parent | d45b5f6510da0e0d0f925bf8e9e443bd7d50bf3c (diff) | |
| download | qpid-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.cpp | 16 |
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); |
