summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Anthony Giusti <kgiusti@apache.org>2011-04-11 19:04:02 +0000
committerKenneth Anthony Giusti <kgiusti@apache.org>2011-04-11 19:04:02 +0000
commitc0aa02908da2cd6d7aa91adcc4508d5a7cd511d9 (patch)
tree969984d183488c4aa73ce03f585ef7c4dbd35308
parente582afaf7d668a1acc1a13fb58fdfce486a15f30 (diff)
downloadqpid-python-c0aa02908da2cd6d7aa91adcc4508d5a7cd511d9.tar.gz
QPID-3197: prevent async command completer from accessing session's connection when session is detached
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1091167 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/cpp/src/qpid/broker/SessionState.cpp22
-rw-r--r--qpid/cpp/src/qpid/broker/SessionState.h7
2 files changed, 26 insertions, 3 deletions
diff --git a/qpid/cpp/src/qpid/broker/SessionState.cpp b/qpid/cpp/src/qpid/broker/SessionState.cpp
index 18dbf63487..eca1883bd9 100644
--- a/qpid/cpp/src/qpid/broker/SessionState.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionState.cpp
@@ -127,6 +127,7 @@ bool SessionState::isLocal(const ConnectionToken* t) const
void SessionState::detach() {
QPID_LOG(debug, getId() << ": detached on broker.");
+ asyncCommandCompleter->detached();
disableOutput();
handler = 0;
if (mgmtObject != 0)
@@ -147,6 +148,7 @@ void SessionState::attach(SessionHandler& h) {
mgmtObject->set_connectionRef (h.getConnection().GetManagementObject()->getObjectId());
mgmtObject->set_channelId (h.getChannel());
}
+ asyncCommandCompleter->attached();
}
void SessionState::abort() {
@@ -486,7 +488,7 @@ void SessionState::AsyncCommandCompleter::scheduleMsgCompletion(SequenceNumber c
{
qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- if (session) {
+ if (session && isAttached) {
MessageInfo msg(cmd, requiresAccept, requiresSync);
completedMsgs.push_back(msg);
if (completedMsgs.size() == 1) {
@@ -522,4 +524,22 @@ void SessionState::AsyncCommandCompleter::cancel()
session = 0;
}
+
+/** inform the completer that the session has attached,
+ * allows command completion scheduling from any thread */
+void SessionState::AsyncCommandCompleter::attached()
+{
+ qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
+ isAttached = true;
+}
+
+
+/** inform the completer that the session has detached,
+ * disables command completion scheduling from any thread */
+void SessionState::AsyncCommandCompleter::detached()
+{
+ qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
+ isAttached = false;
+}
+
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/SessionState.h b/qpid/cpp/src/qpid/broker/SessionState.h
index 2250940102..e847b3fa04 100644
--- a/qpid/cpp/src/qpid/broker/SessionState.h
+++ b/qpid/cpp/src/qpid/broker/SessionState.h
@@ -187,6 +187,7 @@ class SessionState : public qpid::SessionState,
class AsyncCommandCompleter : public RefCounted {
private:
SessionState *session;
+ bool isAttached;
qpid::sys::Mutex completerLock;
// special-case message.transfer commands for optimization
@@ -205,8 +206,8 @@ class SessionState : public qpid::SessionState,
/** for scheduling a run of "completeCommands()" on the IO thread */
static void schedule(boost::intrusive_ptr<AsyncCommandCompleter>);
- public:
- AsyncCommandCompleter(SessionState *s) : session(s) {};
+ public:
+ AsyncCommandCompleter(SessionState *s) : session(s), isAttached(s->isAttached()) {};
~AsyncCommandCompleter() {};
/** schedule the completion of an ingress message.transfer command */
@@ -214,6 +215,8 @@ class SessionState : public qpid::SessionState,
bool requiresAccept,
bool requiresSync);
void cancel(); // called by SessionState destructor.
+ void attached(); // called by SessionState on attach()
+ void detached(); // called by SessionState on detach()
};
boost::intrusive_ptr<AsyncCommandCompleter> asyncCommandCompleter;