Cocoa integration: do not use released session
QTBUG_10735_crashWithDialog started to show flakyness recently - it crashes, but not every time (which fits the definition of UB perfectly). While the test itself is doing weird things and puts our event dispatcher into a weird state, our API allows to: 1. Using QDialog to enter event loop (with runModalSession under the hood), then ... 2. to call from a slot (e.g. timer-attached) QApplication::closeAllWindows() while ... 3. we are still inside that special loop and using the 'session' object, thus ... 4. on the next iteration with [NSApp runModalSession:session] we'll re-use already released session (released by endModalSession which in turn was called indirectly by closeAllWindows). And Cocoa gives us a warning/hint: "Use of freed session detected. Do not call runModalSession: after calling endModalSesion:." Task-number: QTBUG-62589 Change-Id: Ie651cee1fba43cfd2b0fc44af5eddc5fd52e2907 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>bb10
parent
de6d6eb13e
commit
0270651dda
|
|
@ -401,8 +401,18 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
|
|||
// [NSApp run], which is the normal code path for cocoa applications.
|
||||
if (NSModalSession session = d->currentModalSession()) {
|
||||
QBoolBlocker execGuard(d->currentExecIsNSAppRun, false);
|
||||
while ([NSApp runModalSession:session] == NSModalResponseContinue && !d->interrupt)
|
||||
while ([NSApp runModalSession:session] == NSModalResponseContinue && !d->interrupt) {
|
||||
qt_mac_waitForMoreEvents(NSModalPanelRunLoopMode);
|
||||
if (session != d->currentModalSessionCached) {
|
||||
// It's possible to release the current modal session
|
||||
// while we are in this loop, for example, by closing all
|
||||
// windows from a slot via QApplication::closeAllWindows.
|
||||
// In this case we cannot use 'session' anymore. A warning
|
||||
// from Cocoa is: "Use of freed session detected. Do not
|
||||
// call runModalSession: after calling endModalSesion:."
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!d->interrupt && session == d->currentModalSessionCached) {
|
||||
// Someone called [NSApp stopModal:] from outside the event
|
||||
|
|
|
|||
Loading…
Reference in New Issue