Darwin: Remove QMacAutoReleasePool heap allocation detection

This is handled by the Objective-C runtime nowadays, where it will
abort if the situation is detected, with the option to break on
objc_autoreleasePoolInvalid to debug the situation.

Pick-to: 6.5
Change-Id: Idf2c4aacc77e41a3deebf270303f4f13cfb0819b
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
bb10
Tor Arne Vestbø 2023-05-09 16:17:34 +02:00
parent f4b338833e
commit e95f03f989
2 changed files with 3 additions and 68 deletions

View File

@ -217,38 +217,7 @@ QT_USE_NAMESPACE
@interface QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) : NSObject
@end
@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) {
NSAutoreleasePool **m_pool;
}
- (instancetype)initWithPool:(NSAutoreleasePool **)pool
{
if ((self = [self init]))
m_pool = pool;
return self;
}
- (void)dealloc
{
if (*m_pool) {
// The pool is still valid, which means we're not being drained from
// the corresponding QMacAutoReleasePool (see below).
// QMacAutoReleasePool has only a single member, the NSAutoreleasePool*
// so the address of that member is also the QMacAutoReleasePool itself.
QMacAutoReleasePool *pool = reinterpret_cast<QMacAutoReleasePool *>(m_pool);
qWarning() << "Premature drain of" << pool << "This can happen if you've allocated"
<< "the pool on the heap, or as a member of a heap-allocated object. This is not a"
<< "supported use of QMacAutoReleasePool, and might result in crashes when objects"
<< "in the pool are deallocated and then used later on under the assumption they"
<< "will be valid until" << pool << "has been drained.";
// Reset the pool so that it's not drained again later on
*m_pool = nullptr;
}
[super dealloc];
}
@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker)
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAutoReleasePoolTracker);
@ -291,28 +260,15 @@ QMacAutoReleasePool::QMacAutoReleasePool()
}
#endif
[[[trackerClass alloc] initWithPool:
reinterpret_cast<NSAutoreleasePool **>(&pool)] autorelease];
[[trackerClass new] autorelease];
}
QMacAutoReleasePool::~QMacAutoReleasePool()
{
if (!pool) {
qWarning() << "Prematurely drained pool" << this << "finally drained. Any objects belonging"
<< "to this pool have already been released, and have potentially been invalid since the"
<< "premature drain earlier on.";
return;
}
// Save and reset pool before draining, so that the pool tracker can know
// that it's being drained by its owning pool.
NSAutoreleasePool *savedPool = static_cast<NSAutoreleasePool*>(pool);
pool = nullptr;
// Drain behaves the same as release, with the advantage that
// if we're ever used in a garbage-collected environment, the
// drain acts as a hint to the garbage collector to collect.
[savedPool drain];
[static_cast<NSAutoreleasePool*>(pool) drain];
}
#ifndef QT_NO_DEBUG_STREAM

View File

@ -14,7 +14,6 @@ private slots:
void noPool();
void rootLevelPool();
void stackAllocatedPool();
void heapAllocatedPool();
};
static id lastDeallocedObject = nil;
@ -63,26 +62,6 @@ void tst_QMacAutoreleasePool::stackAllocatedPool()
[pool drain];
}
void tst_QMacAutoreleasePool::heapAllocatedPool()
{
// The special case, a pool allocated on the heap, or as a member of a
// heap allocated object. This is not a supported use of QMacAutoReleasePool,
// and will result in warnings if the pool is prematurely drained.
NSObject *allocedObject = nil;
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
QMacAutoReleasePool *qtPool = nullptr;
{
qtPool = new QMacAutoReleasePool;
allocedObject = [[[DeallocTracker alloc] init] autorelease];
}
[pool drain];
delete qtPool;
}
QCOMPARE(lastDeallocedObject, allocedObject);
}
QTEST_APPLESS_MAIN(tst_QMacAutoreleasePool)
#include "tst_qmacautoreleasepool.moc"