[Libwebsockets] [PATCH] Replace pipe with eventfd when available

Olivier Langlois olivier at olivierlanglois.net
Sat Feb 8 22:30:04 CET 2020


>From eventfd man page:
Applications can use an eventfd file descriptor instead of a pipe (see
pipe(2)) in all cases where a pipe is used simply to signal events.
The kernel overhead of an eventfd file descriptor is much lower than
that of a pipe, and only one file descriptor is required
(versus the two required for a pipe).
---
 CMakeLists.txt                        |  1 +
 cmake/lws_config.h.in                 |  1 +
 lib/plat/unix/private-lib-plat-unix.h |  3 +++
 lib/plat/unix/unix-pipe.c             | 12 ++++++++++--
 lib/roles/pipe/ops-pipe.c             |  6 +++++-
 5 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0b3d9f12..66e83585 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -851,6 +851,7 @@ CHECK_FUNCTION_EXISTS(atoll LWS_HAVE_ATOLL)
 CHECK_FUNCTION_EXISTS(_atoi64 LWS_HAVE__ATOI64)
 CHECK_FUNCTION_EXISTS(_stat32i64 LWS_HAVE__STAT32I64)
 CHECK_FUNCTION_EXISTS(clock_gettime LWS_HAVE_CLOCK_GETTIME)
+CHECK_FUNCTION_EXISTS(eventfd LWS_HAVE_EVENTFD)
 
 if (NOT LWS_HAVE_GETIFADDRS)
 	if (LWS_WITHOUT_BUILTIN_GETIFADDRS)
diff --git a/cmake/lws_config.h.in b/cmake/lws_config.h.in
index 29425e42..0a845e70 100644
--- a/cmake/lws_config.h.in
+++ b/cmake/lws_config.h.in
@@ -55,6 +55,7 @@
 #cmakedefine LWS_HAVE_NEW_UV_VERSION_H
 #cmakedefine LWS_HAVE_OPENSSL_ECDH_H
 #cmakedefine LWS_HAVE_PIPE2
+#cmakedefine LWS_HAVE_EVENTFD
 #cmakedefine LWS_HAVE_PTHREAD_H
 #cmakedefine LWS_HAVE_RSA_SET0_KEY
 #cmakedefine LWS_HAVE_RSA_verify_pss_mgf1
diff --git a/lib/plat/unix/private-lib-plat-unix.h
b/lib/plat/unix/private-lib-plat-unix.h
index c7c05a3e..e3262f05 100644
--- a/lib/plat/unix/private-lib-plat-unix.h
+++ b/lib/plat/unix/private-lib-plat-unix.h
@@ -46,6 +46,9 @@
 #include <sys/time.h>
 #include <sys/mman.h>
 #include <sys/un.h>
+#if defined(LWS_HAVE_EVENTFD)
+#include <sys/eventfd.h>
+#endif
 
 #if defined(__APPLE__)
 #include <machine/endian.h>
diff --git a/lib/plat/unix/unix-pipe.c b/lib/plat/unix/unix-pipe.c
index 4786170d..7e4e2b3c 100644
--- a/lib/plat/unix/unix-pipe.c
+++ b/lib/plat/unix/unix-pipe.c
@@ -32,8 +32,11 @@ int
 lws_plat_pipe_create(struct lws *wsi)
 {
 	struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi-
> tsi];
-
-#if defined(LWS_HAVE_PIPE2)
+#if defined(LWS_HAVE_EVENTFD)
+	pt->dummy_pipe_fds[0] = eventfd(0, EFD_CLOEXEC|EFD_NONBLOCK);
+	pt->dummy_pipe_fds[1] = -1;
+	return pt->dummy_pipe_fds[0]<0?-1:0;
+#elif defined(LWS_HAVE_PIPE2)
 	return pipe2(pt->dummy_pipe_fds, O_NONBLOCK);
 #else
 	return pipe(pt->dummy_pipe_fds);
@@ -44,12 +47,17 @@ int
 lws_plat_pipe_signal(struct lws *wsi)
 {
 	struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi-
> tsi];
+#if defined(LWS_HAVE_EVENTFD)
+	eventfd_t value = 1;
+	return eventfd_write(pt->dummy_pipe_fds[0], value);
+#else
 	char buf = 0;
 	int n;
 
 	n = write(pt->dummy_pipe_fds[1], &buf, 1);
 
 	return n != 1;
+#endif
 }
 
 void
diff --git a/lib/roles/pipe/ops-pipe.c b/lib/roles/pipe/ops-pipe.c
index 225f3e97..6b1dfe41 100644
--- a/lib/roles/pipe/ops-pipe.c
+++ b/lib/roles/pipe/ops-pipe.c
@@ -28,7 +28,11 @@ static int
 rops_handle_POLLIN_pipe(struct lws_context_per_thread *pt, struct lws
*wsi,
 			struct lws_pollfd *pollfd)
 {
-#if !defined(WIN32) && !defined(_WIN32)
+#if defined(LWS_HAVE_EVENTFD)
+	eventfd_t value;
+	if (eventfd_read(wsi->desc.sockfd, &value) < 0)
+		return LWS_HPI_RET_PLEASE_CLOSE_ME;
+#elif !defined(WIN32) && !defined(_WIN32)
 	char s[100];
 	int n;
 
-- 
2.25.0




More information about the Libwebsockets mailing list