aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vrátil <dvratil@kde.org>2016-09-08 14:03:25 (GMT)
committerDaniel Vrátil <dvratil@kde.org>2016-09-08 14:06:33 (GMT)
commit7650e9f5c9800b4ba2873b122f037947e28086a0 (patch)
treeb1b2367c779753d68bb03a7977affaa1d027c4f3
parent8f4bcd969dfd4e243532b96643c98749ae666a2b (diff)
Fix potential crash when subscriber disconnects
In a situation when the NotifyRunner thread is dispatching notification to a subscriber and the subscriber disconnects, we could get a crash, because the current code would delete the NotificationSubscriber from different thread.
-rw-r--r--src/server/notificationmanager.cpp6
-rw-r--r--src/server/notificationsubscriber.cpp8
2 files changed, 12 insertions, 2 deletions
diff --git a/src/server/notificationmanager.cpp b/src/server/notificationmanager.cpp
index e5617cd..a971471 100644
--- a/src/server/notificationmanager.cpp
+++ b/src/server/notificationmanager.cpp
@@ -146,9 +146,11 @@ public:
void run() Q_DECL_OVERRIDE
{
- if (mSubscriber) {
- Q_FOREACH (const auto &ntf, mNotifications) {
+ Q_FOREACH (const auto &ntf, mNotifications) {
+ if (mSubscriber) {
mSubscriber->notify(ntf);
+ } else {
+ break;
}
}
}
diff --git a/src/server/notificationsubscriber.cpp b/src/server/notificationsubscriber.cpp
index 290d34f..790ea34 100644
--- a/src/server/notificationsubscriber.cpp
+++ b/src/server/notificationsubscriber.cpp
@@ -24,6 +24,7 @@
#include <QLocalSocket>
#include <QDataStream>
+#include <QPointer>
#include <private/protocol_p.h>
#include <private/protocol_exception_p.h>
@@ -64,6 +65,8 @@ NotificationSubscriber::NotificationSubscriber(NotificationManager *manager, qui
NotificationSubscriber::~NotificationSubscriber()
{
+ QMutexLocker locker(&mLock);
+
if (mNotificationDebugging) {
Q_EMIT notificationDebuggingChanged(false);
}
@@ -642,7 +645,12 @@ bool NotificationSubscriber::acceptsNotification(const Protocol::ChangeNotificat
bool NotificationSubscriber::notify(const Protocol::ChangeNotification &notification)
{
+ // Guard against this object being deleted while we are waiting for the lock
+ QPointer<NotificationSubscriber> ptr(this);
QMutexLocker locker(&mLock);
+ if (!ptr) {
+ return false;
+ }
if (acceptsNotification(notification)) {
QMetaObject::invokeMethod(this, "writeNotification", Qt::QueuedConnection,