Save two system calls for setting a socket non-blocking on Linux

Linux's socket(2) system call can take SOCK_NONBLOCK and let us avoid
the extra two fcntl(2) to change the setting after it's created.

Change-Id: Ie0d7a2d51acc21acd850cbee6d0f76e27b1ae859
Reviewed-by: Richard J. Moore <rich@kde.org>
This commit is contained in:
Thiago Macieira 2014-12-24 17:01:52 -02:00
parent 0fa7374f1d
commit d866f6e886
5 changed files with 22 additions and 23 deletions

View File

@ -235,19 +235,11 @@ void QLocalSocket::connectToServer(OpenMode openMode)
} }
// create the socket // create the socket
if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0))) { if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0, O_NONBLOCK))) {
d->errorOccurred(UnsupportedSocketOperationError, d->errorOccurred(UnsupportedSocketOperationError,
QLatin1String("QLocalSocket::connectToServer")); QLatin1String("QLocalSocket::connectToServer"));
return; return;
} }
// set non blocking so we can try to connect and it won't wait
int flags = fcntl(d->connectingSocket, F_GETFL, 0);
if (-1 == flags
|| -1 == (fcntl(d->connectingSocket, F_SETFL, flags | O_NONBLOCK))) {
d->errorOccurred(UnknownSocketError,
QLatin1String("QLocalSocket::connectToServer"));
return;
}
// _q_connectToSocket does the actual connecting // _q_connectToSocket does the actual connecting
d->connectingName = d->serverName; d->connectingName = d->serverName;

View File

@ -357,14 +357,6 @@ bool QNativeSocketEngine::initialize(QAbstractSocket::SocketType socketType, QAb
return false; return false;
} }
// Make the socket nonblocking.
if (!setOption(NonBlockingSocketOption, 1)) {
d->setError(QAbstractSocket::UnsupportedSocketOperationError,
QNativeSocketEnginePrivate::NonBlockingInitFailedErrorString);
close();
return false;
}
// Set the broadcasting flag if it's a UDP socket. // Set the broadcasting flag if it's a UDP socket.
if (socketType == QAbstractSocket::UdpSocket if (socketType == QAbstractSocket::UdpSocket
&& !setOption(BroadcastSocketOption, 1)) { && !setOption(BroadcastSocketOption, 1)) {

View File

@ -138,10 +138,10 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) ? AF_INET6 : AF_INET; int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) ? AF_INET6 : AF_INET;
int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM; int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM;
int socket = qt_safe_socket(protocol, type, 0); int socket = qt_safe_socket(protocol, type, 0, O_NONBLOCK);
if (socket < 0 && socketProtocol == QAbstractSocket::AnyIPProtocol && errno == EAFNOSUPPORT) { if (socket < 0 && socketProtocol == QAbstractSocket::AnyIPProtocol && errno == EAFNOSUPPORT) {
protocol = AF_INET; protocol = AF_INET;
socket = qt_safe_socket(protocol, type, 0); socket = qt_safe_socket(protocol, type, 0, O_NONBLOCK);
socketProtocol = QAbstractSocket::IPv4Protocol; socketProtocol = QAbstractSocket::IPv4Protocol;
} }

View File

@ -383,8 +383,15 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
#endif #endif
socketDescriptor = socket; socketDescriptor = socket;
return true;
// Make the socket nonblocking.
if (!setOption(QAbstractSocketEngine::NonBlockingSocketOption, 1)) {
setError(QAbstractSocket::UnsupportedSocketOperationError, NonBlockingInitFailedErrorString);
q_func()->close();
return false;
}
return true;
} }
/*! \internal /*! \internal

View File

@ -768,7 +768,7 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
return false; return false;
} }
socketDescriptor = qintptr(socket.Detach()); socketDescriptor = qintptr(socket.Detach());
return true; break;
} }
case QAbstractSocket::UdpSocket: { case QAbstractSocket::UdpSocket: {
ComPtr<IDatagramSocket> socket; ComPtr<IDatagramSocket> socket;
@ -780,15 +780,23 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
EventRegistrationToken token; EventRegistrationToken token;
socketDescriptor = qintptr(socket.Detach()); socketDescriptor = qintptr(socket.Detach());
udpSocket()->add_MessageReceived(Callback<DatagramReceivedHandler>(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &token); udpSocket()->add_MessageReceived(Callback<DatagramReceivedHandler>(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &token);
return true; break;
} }
default: default:
qWarning("Invalid socket type"); qWarning("Invalid socket type");
return false; return false;
} }
// Make the socket nonblocking.
if (!setOption(QAbstractSocketEngine::NonBlockingSocketOption, 1)) {
setError(QAbstractSocket::UnsupportedSocketOperationError, NonBlockingInitFailedErrorString);
q_func()->close();
return false; return false;
} }
return true;
}
QNativeSocketEnginePrivate::QNativeSocketEnginePrivate() QNativeSocketEnginePrivate::QNativeSocketEnginePrivate()
: QAbstractSocketEnginePrivate() : QAbstractSocketEnginePrivate()
, notifyOnRead(true) , notifyOnRead(true)