diff options
Diffstat (limited to 'src/corelib/kernel/qobject_p.h')
-rw-r--r-- | src/corelib/kernel/qobject_p.h | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 8dd29e05ce..4d5543d34a 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -257,7 +257,10 @@ public: ~ConnectionData() { - deleteOrphaned(orphaned.loadRelaxed()); + Q_ASSERT(ref.loadRelaxed() == 0); + auto *c = orphaned.fetchAndStoreRelaxed(nullptr); + if (c) + deleteOrphaned(c); SignalVector *v = signalVector.loadRelaxed(); if (v) free(v); @@ -304,8 +307,15 @@ public: signalVector.storeRelaxed(newVector); if (vector) { - vector->nextInOrphanList = orphaned.loadRelaxed(); - orphaned.storeRelaxed(ConnectionOrSignalVector::fromSignalVector(vector)); + Connection *o = nullptr; + /* No ABA issue here: When adding a node, we only care about the list head, it doesn't + * matter if the tail changes. + */ + do { + o = orphaned.loadRelaxed(); + vector->nextInOrphanList = o; + } while (!orphaned.testAndSetRelease(o, ConnectionOrSignalVector::fromSignalVector(vector))); + } } int signalVectorCount() const |