From 23d52de3214976ffaaa2331b4b16fe0079afc8dd Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 13 Aug 2017 12:07:37 -0700 Subject: QUdpSocket: use faster ways to get datagram size on Linux and macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With MSG_TRUNC on Linux, recv/recvfrom/recvmsg will return the full size of the datagram, even if it won't fit the buffer you passed. On Darwin, we have a getsockopt() option to get that value. Change-Id: I6e9274c1e7444ad48c81fffd14da7d5b93815f90 Reviewed-by: Tor Arne Vestbø Reviewed-by: Edward Welbourne --- src/network/socket/qnativesocketengine_unix.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 13ceb4c612..a8f756dc31 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -834,7 +834,7 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const QT_SOCKLEN_T storageSize = sizeof(storage); memset(&storage, 0, storageSize); - // Peek 0 bytes into the next message. The size of the message may + // Peek 1 bytes into the next message. The size of the message may // well be 0, so we can't check recvfrom's return value. ssize_t readBytes; do { @@ -855,8 +855,20 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const { - QVarLengthArray udpMessagePeekBuffer(8192); ssize_t recvResult = -1; +#ifdef Q_OS_LINUX + // Linux can return the actual datagram size if we use MSG_TRUNC + char c; + EINTR_LOOP(recvResult, ::recv(socketDescriptor, &c, 1, MSG_PEEK | MSG_TRUNC)); +#elif defined(SO_NREAD) + // macOS can return the actual datagram size if we use SO_NREAD + int value; + socklen_t valuelen = sizeof(value); + recvResult = getsockopt(socketDescriptor, SOL_SOCKET, SO_NREAD, &value, &valuelen); + if (recvResult != -1) + recvResult = value; +#else + QVarLengthArray udpMessagePeekBuffer(8192); for (;;) { // the data written to udpMessagePeekBuffer is discarded, so @@ -872,6 +884,7 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const udpMessagePeekBuffer.resize(udpMessagePeekBuffer.size() * 2); } +#endif #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %zd", recvResult); -- cgit v1.2.3