summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-11-16 11:28:18 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-11-16 11:28:18 +0100
commit74f6131c0a67e0b1d0a656ba80f5fd542d12e743 (patch)
treefba2fb135a5da5690cae11c72b6325ea75fce4b1 /common
parent45c2e6a6be0668aa93b38f528042dc42b780d783 (diff)
downloadsink-74f6131c0a67e0b1d0a656ba80f5fd542d12e743.tar.gz
sink-74f6131c0a67e0b1d0a656ba80f5fd542d12e743.zip
Removed ResourceAccess::Private leak and resolved resulting memory
corruption. It looks like the memory corruption (malloc started to crash) was coming QLocalSocket related signals. According to the docs it's not safe (whatever that means), to delete a QObject with pending signals, so we use deleteLater to schedule it's deletion. This resolved the crashes.
Diffstat (limited to 'common')
-rw-r--r--common/resourceaccess.cpp16
-rw-r--r--common/resourceaccess.h6
2 files changed, 19 insertions, 3 deletions
diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp
index dab6335..201c023 100644
--- a/common/resourceaccess.cpp
+++ b/common/resourceaccess.cpp
@@ -82,6 +82,7 @@ class ResourceAccess::Private
82{ 82{
83public: 83public:
84 Private(const QByteArray &name, const QByteArray &instanceIdentifier, ResourceAccess *ra); 84 Private(const QByteArray &name, const QByteArray &instanceIdentifier, ResourceAccess *ra);
85 ~Private();
85 KAsync::Job<void> tryToConnect(); 86 KAsync::Job<void> tryToConnect();
86 KAsync::Job<void> initializeSocket(); 87 KAsync::Job<void> initializeSocket();
87 void abortPendingOperations(); 88 void abortPendingOperations();
@@ -105,6 +106,9 @@ ResourceAccess::Private::Private(const QByteArray &name, const QByteArray &insta
105 : resourceName(name), resourceInstanceIdentifier(instanceIdentifier), messageId(0), openingSocket(false) 106 : resourceName(name), resourceInstanceIdentifier(instanceIdentifier), messageId(0), openingSocket(false)
106{ 107{
107} 108}
109ResourceAccess::Private::~Private()
110{
111}
108 112
109void ResourceAccess::Private::abortPendingOperations() 113void ResourceAccess::Private::abortPendingOperations()
110{ 114{
@@ -144,7 +148,7 @@ void ResourceAccess::Private::callCallbacks()
144// Connects to server and returns connected socket on success 148// Connects to server and returns connected socket on success
145KAsync::Job<QSharedPointer<QLocalSocket>> ResourceAccess::connectToServer(const QByteArray &identifier) 149KAsync::Job<QSharedPointer<QLocalSocket>> ResourceAccess::connectToServer(const QByteArray &identifier)
146{ 150{
147 auto s = QSharedPointer<QLocalSocket>::create(); 151 auto s = QSharedPointer<QLocalSocket>{new QLocalSocket, &QObject::deleteLater};
148 return KAsync::start<QSharedPointer<QLocalSocket>>([identifier, s](KAsync::Future<QSharedPointer<QLocalSocket>> &future) { 152 return KAsync::start<QSharedPointer<QLocalSocket>>([identifier, s](KAsync::Future<QSharedPointer<QLocalSocket>> &future) {
149 s->setServerName(identifier); 153 s->setServerName(identifier);
150 auto context = new QObject; 154 auto context = new QObject;
@@ -251,6 +255,7 @@ ResourceAccess::~ResourceAccess()
251 if (!d->resultHandler.isEmpty()) { 255 if (!d->resultHandler.isEmpty()) {
252 SinkWarning() << "Left jobs running while shutting down ResourceAccess: " << d->resultHandler.keys(); 256 SinkWarning() << "Left jobs running while shutting down ResourceAccess: " << d->resultHandler.keys();
253 } 257 }
258 delete d;
254} 259}
255 260
256QByteArray ResourceAccess::resourceName() const 261QByteArray ResourceAccess::resourceName() const
@@ -662,6 +667,13 @@ bool ResourceAccess::processMessageBuffer()
662 return d->partialMessageBuffer.size() >= headerSize; 667 return d->partialMessageBuffer.size() >= headerSize;
663} 668}
664 669
670
671
672ResourceAccessFactory::ResourceAccessFactory()
673{
674
675}
676
665ResourceAccessFactory &ResourceAccessFactory::instance() 677ResourceAccessFactory &ResourceAccessFactory::instance()
666{ 678{
667 static ResourceAccessFactory *instance = 0; 679 static ResourceAccessFactory *instance = 0;
@@ -682,7 +694,7 @@ Sink::ResourceAccess::Ptr ResourceAccessFactory::getAccess(const QByteArray &ins
682 } 694 }
683 if (!mCache.contains(instanceIdentifier)) { 695 if (!mCache.contains(instanceIdentifier)) {
684 // Create a new instance if necessary 696 // Create a new instance if necessary
685 auto sharedPointer = Sink::ResourceAccess::Ptr::create(instanceIdentifier, resourceType); 697 auto sharedPointer = Sink::ResourceAccess::Ptr{new Sink::ResourceAccess(instanceIdentifier, resourceType), &QObject::deleteLater};
686 QObject::connect(sharedPointer.data(), &Sink::ResourceAccess::ready, sharedPointer.data(), [this, instanceIdentifier](bool ready) { 698 QObject::connect(sharedPointer.data(), &Sink::ResourceAccess::ready, sharedPointer.data(), [this, instanceIdentifier](bool ready) {
687 if (!ready) { 699 if (!ready) {
688 //We want to remove, but we don't want shared pointer to be destroyed until end of the function as this might trigger further steps. 700 //We want to remove, but we don't want shared pointer to be destroyed until end of the function as this might trigger further steps.
diff --git a/common/resourceaccess.h b/common/resourceaccess.h
index 7df6a1b..9387e99 100644
--- a/common/resourceaccess.h
+++ b/common/resourceaccess.h
@@ -44,6 +44,7 @@ public:
44 typedef QSharedPointer<ResourceAccessInterface> Ptr; 44 typedef QSharedPointer<ResourceAccessInterface> Ptr;
45 45
46 ResourceAccessInterface() 46 ResourceAccessInterface()
47 : QObject()
47 { 48 {
48 } 49 }
49 virtual ~ResourceAccessInterface() 50 virtual ~ResourceAccessInterface()
@@ -110,7 +111,7 @@ public:
110 typedef QSharedPointer<ResourceAccess> Ptr; 111 typedef QSharedPointer<ResourceAccess> Ptr;
111 112
112 ResourceAccess(const QByteArray &resourceInstanceIdentifier, const QByteArray &resourceType); 113 ResourceAccess(const QByteArray &resourceInstanceIdentifier, const QByteArray &resourceType);
113 ~ResourceAccess(); 114 virtual ~ResourceAccess();
114 115
115 QByteArray resourceName() const; 116 QByteArray resourceName() const;
116 bool isReady() const; 117 bool isReady() const;
@@ -167,6 +168,9 @@ public:
167 static ResourceAccessFactory &instance(); 168 static ResourceAccessFactory &instance();
168 Sink::ResourceAccess::Ptr getAccess(const QByteArray &instanceIdentifier, const QByteArray resourceType); 169 Sink::ResourceAccess::Ptr getAccess(const QByteArray &instanceIdentifier, const QByteArray resourceType);
169 170
171private:
172 ResourceAccessFactory();
173
170 QHash<QByteArray, QWeakPointer<Sink::ResourceAccess>> mWeakCache; 174 QHash<QByteArray, QWeakPointer<Sink::ResourceAccess>> mWeakCache;
171 QHash<QByteArray, Sink::ResourceAccess::Ptr> mCache; 175 QHash<QByteArray, Sink::ResourceAccess::Ptr> mCache;
172 QHash<QByteArray, QSharedPointer<QTimer>> mTimer; 176 QHash<QByteArray, QSharedPointer<QTimer>> mTimer;