diff options
author | Norwegian Rock Cat <qt-info@nokia.com> | 2009-07-20 08:58:28 (GMT) |
---|---|---|
committer | Norwegian Rock Cat <qt-info@nokia.com> | 2009-07-20 09:19:51 (GMT) |
commit | 84abdaa41e6c3bde6ac653e02bd72300b6681572 (patch) | |
tree | bcf074accb5755987f5aeaaaa0f3c3fadf406d42 /src | |
parent | d3a2ba13342880e2912b9a669c8b6f8bc217eb56 (diff) | |
download | Qt-84abdaa41e6c3bde6ac653e02bd72300b6681572.zip Qt-84abdaa41e6c3bde6ac653e02bd72300b6681572.tar.gz Qt-84abdaa41e6c3bde6ac653e02bd72300b6681572.tar.bz2 |
Fix crash when native socket notifiers would send a notification after being disabled.
Spend a lot of time looking at this and at the CoreFoundation source
code and it seems that we really do get a notification even after the
notifier is disabled. I suspect there's a race condition between when we
disable the socket notifier, but the kernel flags it as needing a read,
then CoreFoundation just sends the notification without checking if the
CFSocket has been disabled. No further notifications come of course.
Since this breaks the invariant that was set in the assert, I'm
replacing it with an if check.
Task-number: 258198
Reviewed-by: Bradley T. Hughes
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qeventdispatcher_mac.mm | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index 99a1fc1..cde0c47 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -264,12 +264,16 @@ void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CF int nativeSocket = CFSocketGetNative(s); MacSocketInfo *socketInfo = eventDispatcher->macSockets.value(nativeSocket); QEvent notifierEvent(QEvent::SockAct); + + // There is a race condition that happen where we disable the notifier and + // the kernel still has a notification to pass on. We then get this + // notification after we've successfully disabled the CFSocket, but our Qt + // notifier is now gone. The upshot is we have to check the notifier + // everytime. if (callbackType == kCFSocketReadCallBack) { - Q_ASSERT(socketInfo->readNotifier); - QApplication::sendEvent(socketInfo->readNotifier, ¬ifierEvent); + if (socketInfo->readNotifier) + QApplication::sendEvent(socketInfo->readNotifier, ¬ifierEvent); } else if (callbackType == kCFSocketWriteCallBack) { - // ### Bug in Apple socket notifiers seems to send write even - // ### after the notifier has been disabled, need to investigate further. if (socketInfo->writeNotifier) QApplication::sendEvent(socketInfo->writeNotifier, ¬ifierEvent); } |