diff options
author | Liang Qi <liang.qi@qt.io> | 2017-09-26 16:08:55 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-09-26 16:14:54 +0200 |
commit | aadfe7d634de04519102c5827ca885dc2e2199c9 (patch) | |
tree | d92db346ca95332b177036a53f1f6beb2e24fb74 /src/corelib/kernel/qcore_mac_objc.mm | |
parent | 4b6c1448047362b8c38d265e6414f0e3e59b8d37 (diff) | |
parent | a732e16d5fd9dbf8a0289fec9f948b12e9ba2c19 (diff) |
Merge remote-tracking branch 'origin/5.10' into dev
Conflicts:
src/gui/kernel/qguiapplication.cpp
src/platformsupport/input/libinput/qlibinputpointer.cpp
src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
src/plugins/platforms/cocoa/qcocoawindow.h
src/testlib/qtestsystem.h
Change-Id: I5975ffb3261c2dd82fe02ec4e57df7c0950226c5
Diffstat (limited to 'src/corelib/kernel/qcore_mac_objc.mm')
-rw-r--r-- | src/corelib/kernel/qcore_mac_objc.mm | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index db7e55f4b1..24d73fa8be 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -84,18 +84,82 @@ QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TY // ------------------------------------------------------------------------- +QT_END_NAMESPACE +QT_USE_NAMESPACE +@interface QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) : NSObject +{ + NSAutoreleasePool **m_pool; +} +-(id)initWithPool:(NSAutoreleasePool**)pool; +@end +@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) +-(id)initWithPool:(NSAutoreleasePool**)pool +{ + if (self = [super 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]; +} +@end +QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAutoReleasePoolTracker); +QT_BEGIN_NAMESPACE + QMacAutoReleasePool::QMacAutoReleasePool() : pool([[NSAutoreleasePool alloc] init]) { + [[[QMacAutoReleasePoolTracker alloc] initWithPool: + reinterpret_cast<NSAutoreleasePool **>(&pool)] 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. - [static_cast<NSAutoreleasePool*>(pool) drain]; + [savedPool drain]; +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + debug << "QMacAutoReleasePool(" << (const void *)pool << ')'; + return debug; } +#endif // !QT_NO_DEBUG_STREAM #ifdef Q_OS_MACOS /* |