Replace select with poll.
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / ip_adapter / caipserver.c
index f2e71f1..085f060 100644 (file)
@@ -28,6 +28,7 @@
 #ifdef __TIZENRT__
 #include <tinyara/config.h>
 #include <uio.h>
+#include <poll.h>
 #endif
 
 #include "iotivity_config.h"
@@ -52,7 +53,7 @@
 #include <sys/types.h>
 #include <fcntl.h>
 #if !defined(_WIN32)
-#include <sys/select.h>
+#include <sys/poll.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <net/if.h>
@@ -205,7 +206,7 @@ static CAIPPacketReceivedCallback g_packetReceivedCallback = NULL;
 
 static void CAFindReadyMessage();
 #if !defined(WSA_WAIT_EVENT_0)
-static void CASelectReturned(fd_set *readFds, int ret);
+static void CAPollReturned(struct pollfd *readFds, int ret);
 #else
 static void CAEventReturned(CASocketFd_t socket);
 #endif
@@ -274,51 +275,68 @@ static void CAReceiveHandler(void *data)
         caglobals.ip.TYPE.fd = OC_INVALID_SOCKET; \
     }
 
-#define SET(TYPE, FDS) \
-    if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET) \
-    { \
-        FD_SET(caglobals.ip.TYPE.fd, FDS); \
-    }
-
-#define ISSET(TYPE, FDS, FLAGS) \
-    if (caglobals.ip.TYPE.fd != OC_INVALID_SOCKET && FD_ISSET(caglobals.ip.TYPE.fd, FDS)) \
-    { \
-        fd = caglobals.ip.TYPE.fd; \
-        flags = FLAGS; \
-    }
-
+#define SET(TYPE, FDS, COUNT) \
+        FDS[COUNT].fd = caglobals.ip.TYPE.fd; \
+        FDS[COUNT].events = POLLIN;
+
+#define MAX_UDP_SOCK_COUNT 8
+
+static const CASocketFd_t *sockFdPtr[MAX_UDP_SOCK_COUNT] = {
+        &caglobals.ip.u6.fd,
+        &caglobals.ip.u6s.fd,
+        &caglobals.ip.u4.fd,
+        &caglobals.ip.u4s.fd,
+        &caglobals.ip.m6.fd,
+        &caglobals.ip.m6s.fd,
+        &caglobals.ip.m4.fd,
+        &caglobals.ip.m4s.fd
+    };
+
+static const CATransportFlags_t inputflags[MAX_UDP_SOCK_COUNT] = {
+        CA_IPV6,
+        CA_IPV6 | CA_SECURE,
+        CA_IPV4,
+        CA_IPV4 | CA_SECURE,
+        CA_MULTICAST | CA_IPV6,
+        CA_MULTICAST | CA_IPV6 | CA_SECURE,
+        CA_MULTICAST | CA_IPV4,
+        CA_MULTICAST | CA_IPV4 | CA_SECURE
+    };
 
 static void CAFindReadyMessage()
 {
-    fd_set readFds;
-    struct timeval timeout;
-
-    timeout.tv_sec = caglobals.ip.selectTimeout;
-    timeout.tv_usec = 0;
-    struct timeval *tv = caglobals.ip.selectTimeout == -1 ? NULL : &timeout;
-
-    FD_ZERO(&readFds);
-    SET(u6,  &readFds)
-    SET(u6s, &readFds)
-    SET(u4,  &readFds)
-    SET(u4s, &readFds)
-    SET(m6,  &readFds)
-    SET(m6s, &readFds)
-    SET(m4,  &readFds)
-    SET(m4s, &readFds)
+    struct pollfd readFds[MAX_UDP_SOCK_COUNT + 2]; // 8 UDP sockets, 1 netlink and 1 read pipe socket fd
+    int timeout = (caglobals.ip.selectTimeout * 1000);
+    int counter = 0;
+
+    SET(u6, readFds, counter);
+    counter++;
+    SET(u6s, readFds, counter);
+    counter++;
+    SET(u4, readFds, counter);
+    counter++;
+    SET(u4s, readFds, counter);
+    counter++;
+    SET(m6, readFds, counter);
+    counter++;
+    SET(m6s, readFds, counter);
+    counter++;
+    SET(m4, readFds, counter);
+    counter++;
+    SET(m4s, readFds, counter);
+    counter++;
+
 #ifndef __TIZENRT__
-    if (caglobals.ip.shutdownFds[0] != -1)
-    {
-        FD_SET(caglobals.ip.shutdownFds[0], &readFds);
-    }
-#endif
-    if (caglobals.ip.netlinkFd != OC_INVALID_SOCKET)
-    {
-        FD_SET(caglobals.ip.netlinkFd, &readFds);
-    }
+    readFds[counter].fd = caglobals.ip.shutdownFds[0];
+    readFds[counter].events = POLLIN;
+    counter++;
 
-    int ret = select(caglobals.ip.maxfd + 1, &readFds, NULL, NULL, tv);
+    readFds[counter].fd = caglobals.ip.netlinkFd;
+    readFds[counter].events = POLLIN;
+    counter++;
+#endif
 
+    int ret = poll(readFds, counter, timeout);
     if (caglobals.ip.terminate)
     {
         OIC_LOG_V(INFO, TAG, "Packet receiver Stop request received.");
@@ -340,71 +358,69 @@ static void CAFindReadyMessage()
         u_arraylist_destroy(iflist);
     }
 #endif
-    if (0 < ret)
+    if (ret > 0)
     {
-        CASelectReturned(&readFds, ret);
+        CAPollReturned(readFds, ret);
     }
-    else if (0 > ret)
+    else if (ret < 0)
     {
-        OIC_LOG_V(FATAL, TAG, "select error %s", CAIPS_GET_ERROR);
+        OIC_LOG_V(FATAL, TAG, "poll error %s", CAIPS_GET_ERROR);
     }
 }
 
-static void CASelectReturned(fd_set *readFds, int ret)
+static void CAPollReturned(struct pollfd *readFds, int ret)
 {
     (void)ret;
-    CASocketFd_t fd = OC_INVALID_SOCKET;
-    CATransportFlags_t flags = CA_DEFAULT_FLAGS;
 
-    while (!caglobals.ip.terminate)
+    int counter = 0;
+
+    for (int i = 0; i < MAX_UDP_SOCK_COUNT && !caglobals.ip.terminate; i++)
     {
-        ISSET(u6,  readFds, CA_IPV6)
-        else ISSET(u6s, readFds, CA_IPV6 | CA_SECURE)
-        else ISSET(u4,  readFds, CA_IPV4)
-        else ISSET(u4s, readFds, CA_IPV4 | CA_SECURE)
-        else ISSET(m6,  readFds, CA_MULTICAST | CA_IPV6)
-        else ISSET(m6s, readFds, CA_MULTICAST | CA_IPV6 | CA_SECURE)
-        else ISSET(m4,  readFds, CA_MULTICAST | CA_IPV4)
-        else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE)
-        else if ((caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && FD_ISSET(caglobals.ip.netlinkFd, readFds))
+        if (*sockFdPtr[i] != OC_INVALID_SOCKET && readFds[i].revents == POLLIN)
         {
-#ifndef __TIZENRT__
-            u_arraylist_t *iflist = CAFindInterfaceChange();
-            if (iflist)
-            {
-                uint32_t listLength = u_arraylist_length(iflist);
-                for (uint32_t i = 0; i < listLength; i++)
-                {
-                    CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
-                    if (ifitem)
-                    {
-                        CAProcessNewInterface(ifitem);
-                    }
-                }
-                u_arraylist_destroy(iflist);
-            }
-            break;
-#endif
+            (void)CAReceiveMessage(readFds[i].fd, inputflags[i]);
         }
+        counter++;
+    }
+
 #ifndef __TIZENRT__
-        else if (FD_ISSET(caglobals.ip.shutdownFds[0], readFds))
+    if (caglobals.ip.terminate)
+    {
+        return;
+    }
+
+    if (caglobals.ip.shutdownFds[0] != -1 && readFds[counter].revents != 0)
+    {
+        char buf[10] = {0};
+        ssize_t len = read(caglobals.ip.shutdownFds[0], buf, sizeof (buf));
+        if (-1 != len)
         {
-            char buf[10] = {0};
-            ssize_t len = read(caglobals.ip.shutdownFds[0], buf, sizeof (buf));
-            if (-1 == len)
-            {
-                continue;
-            }
-            break;
+            // Write end of the pipe is closed. Indicates the termination of UDP server.
+            return;
         }
-#endif
-        else
+
+        counter++;
+    }
+
+    if (!caglobals.ip.terminate &&
+           (caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && readFds[counter].revents != 0)
+    {
+        u_arraylist_t *iflist = CAFindInterfaceChange();
+        if (iflist)
         {
-            break;
+            uint32_t listLength = u_arraylist_length(iflist);
+            for (uint32_t i = 0; i < listLength; i++)
+            {
+                CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+                if (ifitem)
+                {
+                    CAProcessNewInterface(ifitem);
+                }
+            }
+            u_arraylist_destroy(iflist);
         }
-        (void)CAReceiveMessage(fd, flags);
-        FD_CLR(fd, readFds);
     }
+#endif
 }
 
 #else // if defined(WSA_WAIT_EVENT_0)
@@ -890,9 +906,6 @@ static CASocketFd_t CACreateSocket(int family, uint16_t *port, bool isMulticast)
     return fd;
 }
 
-#define CHECKFD(FD) \
-    if (FD > caglobals.ip.maxfd) \
-        caglobals.ip.maxfd = FD;
 #define NEWSOCKET(FAMILY, NAME, MULTICAST) \
     if (caglobals.ip.NAME.fd == OC_INVALID_SOCKET) \
     {   \
@@ -902,7 +915,6 @@ static CASocketFd_t CACreateSocket(int family, uint16_t *port, bool isMulticast)
             caglobals.ip.NAME.port = 0; \
             caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \
         }   \
-        CHECKFD(caglobals.ip.NAME.fd)   \
     }   \
 
 void CreateMulticastSocket()
@@ -967,10 +979,6 @@ static void CAInitializeNetlink()
             close(caglobals.ip.netlinkFd);
             caglobals.ip.netlinkFd = OC_INVALID_SOCKET;
         }
-        else
-        {
-            CHECKFD(caglobals.ip.netlinkFd);
-        }
     }
 #elif defined (__TIZENRT__) // pkmsgq
        struct mq_attr lq_attr;
@@ -999,8 +1007,6 @@ static void CAInitializeFastShutdownMechanism()
 #elif defined(HAVE_PIPE2)
 #ifndef __TIZENRT__
     ret = pipe2(caglobals.ip.shutdownFds, O_CLOEXEC);
-    CHECKFD(caglobals.ip.shutdownFds[0]);
-    CHECKFD(caglobals.ip.shutdownFds[1]);
 #endif
 #else
 #ifndef __TIZENRT__
@@ -1028,8 +1034,6 @@ static void CAInitializeFastShutdownMechanism()
             caglobals.ip.shutdownFds[1] = -1;
         }
     }
-    CHECKFD(caglobals.ip.shutdownFds[0]);
-    CHECKFD(caglobals.ip.shutdownFds[1]);
 #endif
 #endif
     if (-1 == ret)