All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] pseudo: use epoll API on Linux
@ 2017-09-15 14:20 Alexander Kanavin
  2017-09-15 14:42 ` Alexander Kanavin
  0 siblings, 1 reply; 5+ messages in thread
From: Alexander Kanavin @ 2017-09-15 14:20 UTC (permalink / raw)
  To: openembedded-core, seebs

The idea came up here:
https://bugzilla.yoctoproject.org/show_bug.cgi?id=11309
and here:
http://lists.openembedded.org/pipermail/openembedded-core/2017-August/141491.html

Signed-off-by: Alexander Kanavin <alexander.kanavin@linux.intel.com>
---
 .../pseudo/files/0001-Use-epoll-API-on-Linux.patch | 253 +++++++++++++++++++++
 meta/recipes-devtools/pseudo/pseudo_1.8.2.bb       |   1 +
 2 files changed, 254 insertions(+)
 create mode 100644 meta/recipes-devtools/pseudo/files/0001-Use-epoll-API-on-Linux.patch

diff --git a/meta/recipes-devtools/pseudo/files/0001-Use-epoll-API-on-Linux.patch b/meta/recipes-devtools/pseudo/files/0001-Use-epoll-API-on-Linux.patch
new file mode 100644
index 00000000000..38b98fae37e
--- /dev/null
+++ b/meta/recipes-devtools/pseudo/files/0001-Use-epoll-API-on-Linux.patch
@@ -0,0 +1,253 @@
+From 191e8a778276ad2e1516a887dc8768fbc3762c77 Mon Sep 17 00:00:00 2001
+From: Alexander Kanavin <alex.kanavin@gmail.com>
+Date: Fri, 15 Sep 2017 17:00:14 +0300
+Subject: [PATCH] Use epoll API on Linux
+
+Upstream-Status: Pending
+Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
+---
+ enums/exit_status.in |   3 +
+ pseudo_server.c      | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 167 insertions(+), 2 deletions(-)
+
+diff --git a/enums/exit_status.in b/enums/exit_status.in
+index 6be44d3..88f94cd 100644
+--- a/enums/exit_status.in
++++ b/enums/exit_status.in
+@@ -18,3 +18,6 @@ listen_fd, "server loop had no valid listen fd"
+ pseudo_loaded, "server couldn't get out of pseudo environment"
+ pseudo_prefix, "couldn't get valid pseudo prefix"
+ pseudo_invocation, "invalid server command arguments"
++epoll_create, "epoll_create() failed"
++epoll_ctl, "epoll_ctl() failed"
++
+diff --git a/pseudo_server.c b/pseudo_server.c
+index ff16efd..f4f11fe 100644
+--- a/pseudo_server.c
++++ b/pseudo_server.c
+@@ -32,6 +32,7 @@
+ #include <sys/un.h>
+ #include <sys/stat.h>
+ #include <sys/wait.h>
++#include <sys/epoll.h>
+ #include <signal.h>
+ 
+ #include "pseudo.h"
+@@ -59,6 +60,7 @@ static int active_clients = 0, highest_client = 0, max_clients = 0;
+ 
+ #define LOOP_DELAY 2
+ #define DEFAULT_PSEUDO_SERVER_TIMEOUT 30
++#define EPOLL_MAX_EVENTS 10
+ int pseudo_server_timeout = DEFAULT_PSEUDO_SERVER_TIMEOUT;
+ static int die_peacefully = 0;
+ static int die_forcefully = 0;
+@@ -81,6 +83,7 @@ static int messages = 0, responses = 0;
+ static struct timeval message_time = { .tv_sec = 0 };
+ 
+ static void pseudo_server_loop(void);
++static void pseudo_server_loop_epoll(void);
+ 
+ /* helper function to make a directory, just like mkdir -p.
+  * Can't use system() because the child shell would end up trying
+@@ -369,12 +372,16 @@ pseudo_server_start(int daemonize) {
+ 			kill(ppid, SIGUSR1);
+ 		}
+ 	}
++#ifdef PSEUDO_PORT_LINUX
++	pseudo_server_loop_epoll();
++#else
+ 	pseudo_server_loop();
++#endif
+ 	return 0;
+ }
+ 
+ /* mess with internal tables as needed */
+-static void
++static unsigned int
+ open_client(int fd) {
+ 	pseudo_client_t *new_clients;
+ 	int i;
+@@ -390,7 +397,7 @@ open_client(int fd) {
+ 			++active_clients;
+ 			if (i > highest_client)
+ 				highest_client = i;
+-			return;
++			return i;
+ 		}
+ 	}
+ 
+@@ -414,9 +421,11 @@ open_client(int fd) {
+ 
+ 		max_clients += 16;
+ 		++active_clients;
++		return max_clients - 16;
+ 	} else {
+ 		pseudo_diag("error allocating new client, fd %d\n", fd);
+ 		close(fd);
++		return 0;
+ 	}
+ }
+ 
+@@ -566,6 +575,159 @@ serve_client(int i) {
+ 	}
+ }
+ 
++static void pseudo_server_loop_epoll(void)
++{
++	struct sockaddr_un client;
++	socklen_t len;
++        int i;
++        int rc;
++        int fd;
++	int timeout;
++	struct epoll_event ev, events[EPOLL_MAX_EVENTS];
++	int loop_timeout = pseudo_server_timeout;
++
++	clients = malloc(16 * sizeof(*clients));
++
++	clients[0].fd = listen_fd;
++	clients[0].pid = getpid();
++
++	for (i = 1; i < 16; ++i) {
++		clients[i].fd = -1;
++		clients[i].pid = 0;
++		clients[i].tag = NULL;
++		clients[i].program = NULL;
++	}
++
++	active_clients = 1;
++	max_clients = 16;
++	highest_client = 0;
++
++	pseudo_debug(PDBGF_SERVER, "server loop started.\n");
++	if (listen_fd < 0) {
++		pseudo_diag("got into loop with no valid listen fd.\n");
++		exit(PSEUDO_EXIT_LISTEN_FD);
++	}
++
++	timeout = LOOP_DELAY * 1000;
++
++	int epollfd = epoll_create1(0);
++	if (epollfd == -1) {
++		pseudo_diag("epoll_create1() failed.\n");
++		exit(PSEUDO_EXIT_EPOLL_CREATE);
++	}
++	ev.events = EPOLLIN;
++	ev.data.u64 = 0;
++	if (epoll_ctl(epollfd, EPOLL_CTL_ADD, clients[0].fd, &ev) == -1) {
++		pseudo_diag("epoll_ctl() failed with listening socket.\n");
++		exit(PSEUDO_EXIT_EPOLL_CTL);
++	}
++
++	pdb_log_msg(SEVERITY_INFO, NULL, NULL, NULL, "server started (pid %d)", getpid());
++
++        for (;;) {
++		rc = epoll_wait(epollfd, events, EPOLL_MAX_EVENTS, timeout);
++		if (rc == 0 || (rc == -1 && errno == EINTR)) {
++			/* If there's no clients, start timing out.  If there
++			 * are active clients, never time out.
++			 */
++			if (active_clients == 1) {
++				loop_timeout -= LOOP_DELAY;
++                                /* maybe flush database to disk */
++                                pdb_maybe_backup();
++				if (loop_timeout <= 0) {
++					pseudo_debug(PDBGF_SERVER, "no more clients, got bored.\n");
++					die_peacefully = 1;
++				} else {
++					/* display this if not exiting */
++					pseudo_debug(PDBGF_SERVER | PDBGF_BENCHMARK, "%d messages handled in %.4f seconds, %d responses\n",
++						messages,
++						(double) message_time.tv_sec +
++						(double) message_time.tv_usec / 1000000.0,
++                                                responses);
++				}
++			}
++		} else if (rc > 0) {
++			loop_timeout = pseudo_server_timeout;
++			for (i = 0; i < rc; ++i) {
++				if (clients[events[i].data.u64].fd == listen_fd) {
++					if (!die_forcefully) {
++						len = sizeof(client);
++						if ((fd = accept(listen_fd, (struct sockaddr *) &client, &len)) != -1) {
++						/* Don't allow clients to end up on fd 2, because glibc's
++						 * malloc debug uses that fd unconditionally.
++						 */
++							if (fd == 2) {
++								int newfd = fcntl(fd, F_DUPFD, 3);
++								close(fd);
++								fd = newfd;
++							}
++							pseudo_debug(PDBGF_SERVER, "new client fd %d\n", fd);
++		                                        /* A new client implicitly cancels any
++		                                         * previous shutdown request, or a
++		                                         * shutdown for lack of clients.
++		                                         */
++		                                        pseudo_server_timeout = DEFAULT_PSEUDO_SERVER_TIMEOUT;
++		                                        die_peacefully = 0;
++
++							ev.events = EPOLLIN;
++							ev.data.u64 = open_client(fd);
++							if (ev.data.u64 != 0 && epoll_ctl(epollfd, EPOLL_CTL_ADD, clients[ev.data.u64].fd, &ev) == -1) {
++								pseudo_diag("epoll_ctl() failed with accepted socket.\n");
++								exit(PSEUDO_EXIT_EPOLL_CTL);
++							}
++						} else if (errno == EMFILE) {
++							// select() loop would drop a client here, we do nothing (for now)
++							pseudo_debug(PDBGF_SERVER, "Hit max open files.\n");
++						}
++					}
++				} else {
++					struct timeval tv1, tv2;
++                                        int rc;
++					gettimeofday(&tv1, NULL);
++					rc = serve_client(events[i].data.u64);
++					gettimeofday(&tv2, NULL);
++					++messages;
++                                        if (rc == 0)
++                                                ++responses;
++					message_time.tv_sec += (tv2.tv_sec - tv1.tv_sec);
++					message_time.tv_usec += (tv2.tv_usec - tv1.tv_usec);
++					if (message_time.tv_usec < 0) {
++						message_time.tv_usec += 1000000;
++						--message_time.tv_sec;
++					} else while (message_time.tv_usec > 1000000) {
++						message_time.tv_usec -= 1000000;
++						++message_time.tv_sec;
++					}
++				}
++				if (die_forcefully)
++					break;
++			}
++			pseudo_debug(PDBGF_SERVER, "server loop complete [%d clients left]\n", active_clients);
++		} else {
++			pseudo_diag("epoll_wait failed: %s\n", strerror(errno));
++			break;
++		}
++		if (die_peacefully || die_forcefully) {
++			pseudo_debug(PDBGF_SERVER, "quitting.\n");
++			pseudo_debug(PDBGF_SERVER | PDBGF_BENCHMARK, "server %d exiting: handled %d messages in %.4f seconds\n",
++				getpid(), messages,
++				(double) message_time.tv_sec +
++				(double) message_time.tv_usec / 1000000.0);
++			pdb_log_msg(SEVERITY_INFO, NULL, NULL, NULL, "server %d exiting: handled %d messages in %.4f seconds",
++				getpid(), messages,
++				(double) message_time.tv_sec +
++				(double) message_time.tv_usec / 1000000.0);
++			/* and at this point, we'll start refusing connections */
++			close(clients[0].fd);
++			/* This is a good place to insert a delay for
++			 * debugging race conditions during startup. */
++			/* usleep(300000); */
++			exit(0);
++		}
++	}
++
++}
++
+ /* get clients, handle messages, shut down.
+  * This doesn't actually do any work, it just calls a ton of things which
+  * do work.
+-- 
+2.14.1
+
diff --git a/meta/recipes-devtools/pseudo/pseudo_1.8.2.bb b/meta/recipes-devtools/pseudo/pseudo_1.8.2.bb
index 9bcd0318926..81853e95c42 100644
--- a/meta/recipes-devtools/pseudo/pseudo_1.8.2.bb
+++ b/meta/recipes-devtools/pseudo/pseudo_1.8.2.bb
@@ -8,6 +8,7 @@ SRC_URI = "http://downloads.yoctoproject.org/releases/pseudo/${BPN}-${PV}.tar.bz
            file://efe0be279901006f939cd357ccee47b651c786da.patch \
            file://b6b68db896f9963558334aff7fca61adde4ec10f.patch \
            file://toomanyfiles.patch \
+           file://0001-Use-epoll-API-on-Linux.patch \
            "
 
 SRC_URI[md5sum] = "7d41e72188fbea1f696c399c1a435675"
-- 
2.14.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] pseudo: use epoll API on Linux
  2017-09-15 14:20 [PATCH] pseudo: use epoll API on Linux Alexander Kanavin
@ 2017-09-15 14:42 ` Alexander Kanavin
  2017-09-16  0:06   ` Trevor Woerner
  0 siblings, 1 reply; 5+ messages in thread
From: Alexander Kanavin @ 2017-09-15 14:42 UTC (permalink / raw)
  To: openembedded-core, seebs

On 09/15/2017 05:20 PM, Alexander Kanavin wrote:

> ++#include <sys/epoll.h>

Forgot to wrap this one into #ifdef PSEUDO_PORT_LINUX as well.



Alex


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] pseudo: use epoll API on Linux
  2017-09-15 14:42 ` Alexander Kanavin
@ 2017-09-16  0:06   ` Trevor Woerner
  2017-09-19 11:20     ` Alexander Kanavin
  0 siblings, 1 reply; 5+ messages in thread
From: Trevor Woerner @ 2017-09-16  0:06 UTC (permalink / raw)
  To: Alexander Kanavin; +Cc: Patches and discussions about the oe-core layer

So, my understand is that pseudo is looking for a new maintainer.
Maybe that person has been found? ;-)


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] pseudo: use epoll API on Linux
  2017-09-16  0:06   ` Trevor Woerner
@ 2017-09-19 11:20     ` Alexander Kanavin
  2017-09-19 17:47       ` Trevor Woerner
  0 siblings, 1 reply; 5+ messages in thread
From: Alexander Kanavin @ 2017-09-19 11:20 UTC (permalink / raw)
  To: Trevor Woerner; +Cc: Patches and discussions about the oe-core layer

On 09/16/2017 03:06 AM, Trevor Woerner wrote:
> So, my understand is that pseudo is looking for a new maintainer.
> Maybe that person has been found? ;-)
> 

If that person is me, then thank you for the trust, but:

a) I had no idea how pseudo works until last week; right now I'm 
familiar with maybe 3% of its code;

b) taking responsibility for these things is unfortunately something of 
a zero-sum game; my main area is maintenance of oe-core content, and 
with Jussi Kukkonen no longer involved in the project, I only expect 
more work, not less. Particularly around graphics, multimedia and 
gnome-related things.


Alex


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] pseudo: use epoll API on Linux
  2017-09-19 11:20     ` Alexander Kanavin
@ 2017-09-19 17:47       ` Trevor Woerner
  0 siblings, 0 replies; 5+ messages in thread
From: Trevor Woerner @ 2017-09-19 17:47 UTC (permalink / raw)
  To: Alexander Kanavin; +Cc: Patches and discussions about the oe-core layer

On Tue, Sep 19, 2017 at 7:20 AM, Alexander Kanavin
<alexander.kanavin@linux.intel.com> wrote:
> and with
> Jussi Kukkonen no longer involved in the project

This is sad news :-(
So long Jussi, and thanks for all the recipes


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-09-19 17:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-15 14:20 [PATCH] pseudo: use epoll API on Linux Alexander Kanavin
2017-09-15 14:42 ` Alexander Kanavin
2017-09-16  0:06   ` Trevor Woerner
2017-09-19 11:20     ` Alexander Kanavin
2017-09-19 17:47       ` Trevor Woerner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.