cleanup frame handlers on channel deletion

In cases where exchanges and queues are added and deleted during
an extended use of a QAmqpClient, the client should internally cleanup
the frame handlers registered for those objects. This patch does that
as well as providing two test cases verifying this behavior for both
QAmqpQueue and QAmqpExchange.
This commit is contained in:
Matt Broadstone 2015-02-06 16:12:58 -05:00
parent bcc6fdba9d
commit 4640a9ad6a
7 changed files with 50 additions and 0 deletions

View File

@ -22,6 +22,10 @@ QAmqpChannelPrivate::QAmqpChannelPrivate(QAmqpChannel *q)
QAmqpChannelPrivate::~QAmqpChannelPrivate()
{
if (!client.isNull()) {
QAmqpClientPrivate *priv = client->d_func();
priv->methodHandlersByChannel[channelNumber].removeAll(this);
}
}
void QAmqpChannelPrivate::init(int channel, QAmqpClient *c)

View File

@ -58,6 +58,7 @@ protected:
Q_PRIVATE_SLOT(d_func(), void _q_disconnected())
friend class QAmqpClientPrivate;
friend class QAmqpExchangePrivate;
};
#endif // QAMQPCHANNEL_H

View File

@ -6,6 +6,7 @@
#define METHOD_ID_ENUM(name, id) name = id, name ## Ok
class QAmqpChannel;
class QAmqpClient;
class QAmqpClientPrivate;
class QAmqpChannelPrivate : public QAmqpMethodFrameHandler

View File

@ -112,6 +112,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_disconnect())
friend class QAmqpChannelPrivate;
friend class QAmqpQueuePrivate;
};

View File

@ -3,6 +3,8 @@
#include <QDataStream>
#include <QFile>
#include "qamqpclient.h"
#include "qamqpclient_p.h"
#include "qamqpqueue.h"
#include "qamqpqueue_p.h"
#include "qamqpexchange.h"
@ -21,6 +23,11 @@ QAmqpQueuePrivate::QAmqpQueuePrivate(QAmqpQueue *q)
QAmqpQueuePrivate::~QAmqpQueuePrivate()
{
if (!client.isNull()) {
QAmqpClientPrivate *priv = client->d_func();
priv->contentHandlerByChannel[channelNumber].removeAll(this);
priv->bodyHandlersByChannel[channelNumber].removeAll(this);
}
}
bool QAmqpQueuePrivate::_q_method(const QAmqpMethodFrame &frame)

View File

@ -26,6 +26,7 @@ private Q_SLOTS:
void confirmsSupport();
void confirmDontLoseMessages();
void passiveDeclareNotFound();
void cleanupOnDeletion();
private:
QScopedPointer<QAmqpClient> client;
@ -199,5 +200,22 @@ void tst_QAMQPExchange::passiveDeclareNotFound()
QCOMPARE(nonExistentExchange->error(), QAMQP::NotFoundError);
}
void tst_QAMQPExchange::cleanupOnDeletion()
{
// create, declare, and close the wrong way
QAmqpExchange *exchange = client->createExchange("test-deletion");
exchange->declare();
QVERIFY(waitForSignal(exchange, SIGNAL(declared())));
exchange->close();
exchange->deleteLater();
// now create, declare, and close the right way
exchange = client->createExchange("test-deletion");
exchange->declare();
QVERIFY(waitForSignal(exchange, SIGNAL(declared())));
exchange->close();
QVERIFY(waitForSignal(exchange, SIGNAL(closed())));
}
QTEST_MAIN(tst_QAMQPExchange)
#include "tst_qamqpexchange.moc"

View File

@ -46,6 +46,7 @@ private Q_SLOTS:
void tableFieldDataTypes();
void messageProperties();
void emptyMessage();
void cleanupOnDeletion();
private:
QScopedPointer<QAmqpClient> client;
@ -653,5 +654,22 @@ void tst_QAMQPQueue::emptyMessage()
QVERIFY(message.payload().isEmpty());
}
void tst_QAMQPQueue::cleanupOnDeletion()
{
// create, declare, and close the wrong way
QAmqpQueue *queue = client->createQueue("test-deletion");
queue->declare();
QVERIFY(waitForSignal(queue, SIGNAL(declared())));
queue->close();
queue->deleteLater();
// now create, declare, and close the right way
queue = client->createQueue("test-deletion");
queue->declare();
QVERIFY(waitForSignal(queue, SIGNAL(declared())));
queue->close();
QVERIFY(waitForSignal(queue, SIGNAL(closed())));
}
QTEST_MAIN(tst_QAMQPQueue)
#include "tst_qamqpqueue.moc"