diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-11-16 11:28:18 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-11-16 11:28:18 +0100 |
commit | 74f6131c0a67e0b1d0a656ba80f5fd542d12e743 (patch) | |
tree | fba2fb135a5da5690cae11c72b6325ea75fce4b1 /common | |
parent | 45c2e6a6be0668aa93b38f528042dc42b780d783 (diff) | |
download | sink-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.cpp | 16 | ||||
-rw-r--r-- | common/resourceaccess.h | 6 |
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 | { |
83 | public: | 83 | public: |
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 | } |
109 | ResourceAccess::Private::~Private() | ||
110 | { | ||
111 | } | ||
108 | 112 | ||
109 | void ResourceAccess::Private::abortPendingOperations() | 113 | void 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 |
145 | KAsync::Job<QSharedPointer<QLocalSocket>> ResourceAccess::connectToServer(const QByteArray &identifier) | 149 | KAsync::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 | ||
256 | QByteArray ResourceAccess::resourceName() const | 261 | QByteArray 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 | |||
672 | ResourceAccessFactory::ResourceAccessFactory() | ||
673 | { | ||
674 | |||
675 | } | ||
676 | |||
665 | ResourceAccessFactory &ResourceAccessFactory::instance() | 677 | ResourceAccessFactory &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 | ||
171 | private: | ||
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; |