1 /**************************************************************************** |
1 /**************************************************************************** |
2 ** |
2 ** |
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
4 ** All rights reserved. |
4 ** All rights reserved. |
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
6 ** |
6 ** |
7 ** This file is part of the QtNetwork module of the Qt Toolkit. |
7 ** This file is part of the QtNetwork module of the Qt Toolkit. |
8 ** |
8 ** |
992 |
992 |
993 qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len) |
993 qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len) |
994 { |
994 { |
995 Q_Q(QNativeSocketEngine); |
995 Q_Q(QNativeSocketEngine); |
996 qint64 ret = 0; |
996 qint64 ret = 0; |
997 // don't send more than 49152 per call to WSASendTo to avoid getting a WSAENOBUFS |
997 qint64 bytesToSend = len; |
|
998 |
998 for (;;) { |
999 for (;;) { |
999 qint64 bytesToSend = qMin<qint64>(49152, len - ret); |
|
1000 WSABUF buf; |
1000 WSABUF buf; |
1001 buf.buf = (char*)data + ret; |
1001 buf.buf = (char*)data + ret; |
1002 buf.len = bytesToSend; |
1002 buf.len = bytesToSend; |
1003 DWORD flags = 0; |
1003 DWORD flags = 0; |
1004 DWORD bytesWritten = 0; |
1004 DWORD bytesWritten = 0; |
1005 |
1005 |
1006 int socketRet = ::WSASend(socketDescriptor, &buf, 1, &bytesWritten, flags, 0,0); |
1006 int socketRet = ::WSASend(socketDescriptor, &buf, 1, &bytesWritten, flags, 0,0); |
1007 |
1007 |
1008 ret += qint64(bytesWritten); |
1008 ret += qint64(bytesWritten); |
1009 |
1009 |
|
1010 int err; |
1010 if (socketRet != SOCKET_ERROR) { |
1011 if (socketRet != SOCKET_ERROR) { |
1011 if (ret == len) |
1012 if (ret == len) |
1012 break; |
1013 break; |
1013 else |
1014 else |
1014 continue; |
1015 continue; |
1015 } else if (WSAGetLastError() == WSAEWOULDBLOCK) { |
1016 } else if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) { |
1016 break; |
1017 break; |
|
1018 } else if (err == WSAENOBUFS) { |
|
1019 // this function used to not send more than 49152 per call to WSASendTo |
|
1020 // to avoid getting a WSAENOBUFS. However this is a performance regression |
|
1021 // and we think it only appears with old windows versions. We now handle the |
|
1022 // WSAENOBUFS and hope it never appears anyway. |
|
1023 // just go on, the next loop run we will try a smaller number |
1017 } else { |
1024 } else { |
1018 int err = WSAGetLastError(); |
|
1019 WS_ERROR_DEBUG(err); |
1025 WS_ERROR_DEBUG(err); |
1020 switch (err) { |
1026 switch (err) { |
1021 case WSAECONNRESET: |
1027 case WSAECONNRESET: |
1022 case WSAECONNABORTED: |
1028 case WSAECONNABORTED: |
1023 ret = -1; |
1029 ret = -1; |
1027 default: |
1033 default: |
1028 break; |
1034 break; |
1029 } |
1035 } |
1030 break; |
1036 break; |
1031 } |
1037 } |
|
1038 |
|
1039 // for next send: |
|
1040 bytesToSend = qMin<qint64>(49152, len - ret); |
1032 } |
1041 } |
1033 |
1042 |
1034 #if defined (QNATIVESOCKETENGINE_DEBUG) |
1043 #if defined (QNATIVESOCKETENGINE_DEBUG) |
1035 qDebug("QNativeSocketEnginePrivate::nativeWrite(%p \"%s\", %li) == %li", |
1044 qDebug("QNativeSocketEnginePrivate::nativeWrite(%p \"%s\", %li) == %li", |
1036 data, qt_prettyDebug(data, qMin((int)ret, 16), (int)ret).data(), (int)len, (int)ret); |
1045 data, qt_prettyDebug(data, qMin((int)ret, 16), (int)ret).data(), (int)len, (int)ret); |
1188 void QNativeSocketEnginePrivate::nativeClose() |
1197 void QNativeSocketEnginePrivate::nativeClose() |
1189 { |
1198 { |
1190 #if defined (QTCPSOCKETENGINE_DEBUG) |
1199 #if defined (QTCPSOCKETENGINE_DEBUG) |
1191 qDebug("QNativeSocketEnginePrivate::nativeClose()"); |
1200 qDebug("QNativeSocketEnginePrivate::nativeClose()"); |
1192 #endif |
1201 #endif |
1193 linger l = {1, 0}; |
1202 // We were doing a setsockopt here before with SO_DONTLINGER. (However with kind of wrong |
1194 ::setsockopt(socketDescriptor, SOL_SOCKET, SO_DONTLINGER, (char*)&l, sizeof(l)); |
1203 // usage of parameters, it wants a BOOL but we used a struct and pretended it to be bool). |
|
1204 // We don't think setting this option should be done here, if a user wants it she/he can |
|
1205 // do it manually with socketDescriptor()/setSocketDescriptor(); |
1195 ::closesocket(socketDescriptor); |
1206 ::closesocket(socketDescriptor); |
1196 } |
1207 } |
1197 |
1208 |
1198 QT_END_NAMESPACE |
1209 QT_END_NAMESPACE |