summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-08-13 12:07:37 -0700
committerThiago Macieira <thiago.macieira@intel.com>2017-08-27 16:38:50 +0000
commit23d52de3214976ffaaa2331b4b16fe0079afc8dd (patch)
tree33cc617fa6ca360e88b5f2ee90359f95d0d2d82b
parent5de734bc18dcf7cf660684c44b5fc6b886a7b88b (diff)
QUdpSocket: use faster ways to get datagram size on Linux and macOS
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ø <tor.arne.vestbo@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp17
1 files 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<char, 8192> 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<char, 8192> 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);