OSDN Git Service

replace select() with poll() in network component
authorIvailo Monev <xakepa10@gmail.com>
Wed, 22 Sep 2021 15:52:51 +0000 (18:52 +0300)
committerIvailo Monev <xakepa10@gmail.com>
Wed, 22 Sep 2021 15:52:51 +0000 (18:52 +0300)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
src/core/kernel/qcore_unix_p.h
src/network/socket/qlocalserver_unix.cpp
src/network/socket/qlocalsocket_unix.cpp
src/network/socket/qnativesocketengine_unix.cpp

index af49456..8c8ab10 100644 (file)
@@ -36,6 +36,7 @@
 #include "qplatformdefs.h"
 #include "qatomic.h"
 
+#include <poll.h>
 #include <string.h>
 #include <sys/wait.h>
 #include <errno.h>
@@ -256,6 +257,23 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
     return ret;
 }
 
+// don't call ::poll, call qt_safe_poll
+static inline int qt_safe_poll(int fd, int events, int timeout, int *revents)
+{
+    struct pollfd pd;
+    ::memset(&pd, 0, sizeof(struct pollfd));
+    pd.fd = fd;
+    pd.events = events;
+    int ret;
+    Q_EINTR_LOOP(ret, ::poll(&pd, 1, timeout));
+    if ((pd.revents & POLLERR) != 0 || (pd.revents & POLLHUP) != 0 || (pd.revents & POLLNVAL) != 0) {
+        // select() compat
+        return -1;
+    }
+    *revents = pd.revents;
+    return ret;
+}
+
 timeval qt_gettime(); // in qelapsedtimer_unix.cpp
 
 // don't call ::select, call qt_safe_select
index 225d9b8..5c6d721 100644 (file)
@@ -162,16 +162,9 @@ void QLocalServerPrivate::_q_onNewConnection()
 
 void QLocalServerPrivate::waitForNewConnection(int msec, bool *timedOut)
 {
-    fd_set readfds;
-    FD_ZERO(&readfds);
-    FD_SET(listenSocket, &readfds);
-
-    timeval timeout;
-    timeout.tv_sec = msec / 1000;
-    timeout.tv_usec = (msec % 1000) * 1000;
-
-    int result = qt_safe_select(listenSocket + 1, &readfds, 0, 0, (msec == -1) ? 0 : &timeout);
-    if (-1 == result) {
+    int revents = 0;
+    int result = qt_safe_poll(listenSocket, POLLIN, msec, &revents);
+    if (result == -1) {
         setError(QLatin1String("QLocalServer::waitForNewConnection"));
         closeServer();
     }
index 2a50178..8d0bc40 100644 (file)
@@ -501,19 +501,12 @@ bool QLocalSocket::waitForConnected(int msec)
         return (state() == ConnectedState);
 
     if (state() == ConnectingState) {
-        fd_set fds;
-        FD_ZERO(&fds);
-        FD_SET(d->connectingSocket, &fds);
-
-        timeval timeout;
-        timeout.tv_sec = msec / 1000;
-        timeout.tv_usec = (msec % 1000) * 1000;
-
-        // timeout can not be 0 or else select will return an error.
+        // if timeout is 0 poll() will return immidiatly.
         if (msec == 0)
-            timeout.tv_usec = 1000;
+            msec = 1000;
 
-        int result = qt_safe_select(d->connectingSocket + 1, &fds, 0, 0, (msec == -1) ? 0 : &timeout);
+        int revents = 0;
+        int result = qt_safe_poll(d->connectingSocket, POLLIN, msec, &revents);
         if (result == -1) {
             d->errorOccurred( QLocalSocket::UnknownSocketError,
                     QLatin1String("QLocalSocket::waitForConnected"));
index c05b355..53fc916 100644 (file)
@@ -987,48 +987,27 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize)
 
 int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const
 {
-    fd_set fds;
-    FD_ZERO(&fds);
-    FD_SET(socketDescriptor, &fds);
-
-    struct timeval tv;
-    tv.tv_sec = timeout / 1000;
-    tv.tv_usec = (timeout % 1000) * 1000;
-
-    int retval;
-    if (selectForRead)
-        retval = qt_safe_select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv);
-    else
-        retval = qt_safe_select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv);
-
-    return retval;
+    int revents = 0;
+    return qt_safe_poll(socketDescriptor, selectForRead ? POLLIN : POLLOUT, timeout, &revents);
 }
 
 int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite,
                        bool *selectForRead, bool *selectForWrite) const
 {
-    fd_set fdread;
-    FD_ZERO(&fdread);
-    if (checkRead)
-        FD_SET(socketDescriptor, &fdread);
-
-    fd_set fdwrite;
-    FD_ZERO(&fdwrite);
-    if (checkWrite)
-        FD_SET(socketDescriptor, &fdwrite);
-
-    struct timeval tv;
-    tv.tv_sec = timeout / 1000;
-    tv.tv_usec = (timeout % 1000) * 1000;
-
-    int ret;
-    ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv);
-
-    if (ret <= 0)
-        return ret;
-    *selectForRead = FD_ISSET(socketDescriptor, &fdread);
-    *selectForWrite = FD_ISSET(socketDescriptor, &fdwrite);
+    int events = 0;
+    if (checkRead) {
+        events |= POLLIN;
+    }
+    if (checkWrite) {
+        events |= POLLOUT;
+    }
+    int revents = 0;
 
+    int ret = qt_safe_poll(socketDescriptor, events, timeout, &revents);
+    if (ret > 0) {
+        *selectForRead = ((revents & POLLIN) != 0);
+        *selectForWrite = ((revents & POLLOUT) != 0);
+    }
     return ret;
 }