Details
-
Bug
-
Resolution: Done
-
P3: Somewhat important
-
5.15.2
-
-
d492245d9f98e410e1748f28a598945244dbafa8 (qt/qtbase/dev) 72c609203b48a684afe51878bd7bd487fe96a103 (qt/qtbase/6.0) 63bdb5dd04478143dda23e273400fc56a30842ad (qt/tqtc-qtbase/5.15)
Description
QCFSocketNotifier implements socket notifications when Cocoa platform plugin is used (Qt GUI applications). However it only registers read and write but not connect callbacks while creating underlying CFSocket object (see codes below taken from QCFSocketNotifier::registerSocketNotifier() function).
socketInfo = new MacSocketInfo(); // Create CFSocket, specify that we want both read and write callbacks (the callbacks // are enabled/disabled later on). const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack; CFSocketContext context = {0, this, 0, 0, 0}; socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context); if (CFSocketIsValid(socketInfo->socket) == false) { qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket"); return; }
Any TCP client socket used in Qt GUI application under macOS will not receive connection completion or failure notifications. It is fine if connection succeeds as write notification will be triggered. However if connection fails, it will not trigger any notification. We will have to wait for the connection timer expiry in QAbstractSocket, which is 30 seconds by default. And as QAbstractSocket try the same address twice, it will take 60 seconds before QAbstractSocket::disconnected to be triggered. Before that no error signals are triggered at all - it is supposed to trigger disconnected immediately when socket connection fails.
The fix would be adding kCFSocketConnectCallback to callbackTypes in QCFSocketNotifier::registerSocketNotifier() and handles it in qt_mac_socket_callback() (just need to trigger the notifications similar to implementations for other platforms).