]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
DEV: poll: add support for epoll
authorWilly Tarreau <w@1wt.eu>
Fri, 25 Nov 2022 15:34:11 +0000 (16:34 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 25 Nov 2022 16:07:22 +0000 (17:07 +0100)
When called with -e, epoll is used instead of poll. The poller does
very little in this code (just checks for any event without waiting) but
that's sufficient to see return values.

dev/poll/poll.c

index 554fd63ca21d99f31be0873e061f0badac802b5e..022c0396f4fc551078e6c2640a8d008166a6f1c5 100644 (file)
@@ -2,6 +2,11 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+
+#ifdef __linux__
+#include <sys/epoll.h>
+#endif
+
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <errno.h>
@@ -33,6 +38,7 @@ int lfd = -1;
 int cfd = -1;
 int sfd = -1;
 int connected = 0;
+int use_epoll = 0;
 struct sockaddr_in saddr, caddr;
 socklen_t salen, calen;
 
@@ -53,6 +59,7 @@ void usage(const char *arg0)
               "args:\n"
               "    -h            display this help\n"
               "    -v            verbose mode (shows ret values)\n"
+              "    -e            use epoll instead of poll\n"
               "    -c <actions>  perform <action> on client side socket\n"
               "    -s <actions>  perform <action> on server side socket\n"
               "    -l <actions>  perform <action> on listening socket\n"
@@ -209,13 +216,56 @@ void do_clo(int fd)
 void do_pol(int fd)
 {
        struct pollfd fds = { .fd = fd, .events = POLLIN|POLLOUT|POLLRDHUP, .revents=0 };
+       int flags, flag;
        int ret;
 
+#ifdef __linux__
+       while (use_epoll) {
+               struct epoll_event evt;
+               static int epoll_fd = -1;
+
+               if (epoll_fd == -1)
+                       epoll_fd = epoll_create(1024);
+               if (epoll_fd == -1)
+                       break;
+               evt.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP;
+               evt.data.fd = fd;
+               epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &evt);
+               ret = epoll_wait(epoll_fd, &evt, 1, 0);
+
+               if (verbose) {
+                       printf("cmd #%d stp #%d: %s(%s=%d): ret=%d%s ev=%#x ", cmd, cmdstep, __FUNCTION__ + 3, side(fd), fd, ret, get_errno(ret), ret > 0 ? evt.events : 0);
+                       if (ret > 0 && evt.events) {
+                               putchar('(');
+
+                               for (flags = evt.events; flags; flags ^= flag) {
+                                       flag = flags ^ (flags & (flags - 1)); // keep lowest bit only
+                                       switch (flag) {
+                                       case EPOLLIN: printf("IN"); break;
+                                       case EPOLLOUT: printf("OUT"); break;
+                                       case EPOLLPRI: printf("PRI"); break;
+                                       case EPOLLHUP: printf("HUP"); break;
+                                       case EPOLLERR: printf("ERR"); break;
+                                       case EPOLLRDHUP: printf("RDHUP"); break;
+                                       default: printf("???[%#x]", flag); break;
+                                       }
+                                       if (flags ^ flag)
+                                               putchar(' ');
+                               }
+                               putchar(')');
+                       }
+                       putchar('\n');
+               }
+
+               evt.data.fd = fd;
+               epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &evt);
+               return;
+       }
+#endif
        ret = poll(&fds, 1, 0);
        if (verbose) {
                printf("cmd #%d stp #%d: %s(%s=%d): ret=%d%s ev=%#x ", cmd, cmdstep, __FUNCTION__ + 3, side(fd), fd, ret, get_errno(ret), ret > 0 ? fds.revents : 0);
                if (ret > 0 && fds.revents) {
-                       int flags, flag;
                        putchar('(');
 
                        for (flags = fds.revents; flags; flags ^= flag) {
@@ -298,6 +348,9 @@ int main(int argc, char **argv)
                case 'v' :
                        verbose++;
                        break;
+               case 'e' :
+                       use_epoll = 1;
+                       break;
                case 'c' :
                        cmd++; cmdstep = 0;
                        if (!connected) {