From 055d274f50564829a233699eb2db4833a63fd1f4 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Wed, 28 Oct 2026 11:52:20 +0300 Subject: [PATCH] Event loops: no sleep on a loop accepting connections tcpnext() and srvspawn() slept a little after accept() failed for want of descriptors or memory, and after a client's memory could not be had, with usleep(): accepting on a fiber of a loop, that held up every client of the loop. srvsleep() waits in the loop there (sockpoll() with no sockets), as tcploop() already did waiting for a slot, and sleeps as before in a thread. Co-Authored-By: Claude Opus 5.5 --- src/mainclient.c | 9 ++++++++- src/maintcp.c | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/mainclient.c b/src/mainclient.c index f9f2f88..074c00c 100644 --- a/src/mainclient.c +++ b/src/mainclient.c @@ -259,6 +259,13 @@ void * threadfunc (void *p) { /* A thread for the client, client_sock for TCP, or a fiber of an event loop. 0 once it runs, the slot in hand going with it. */ +/* usleep(SLEEPTIME * n), but on a fiber of a loop (accepting there) a wait + in the loop, which a sleep would hold up */ +static void srvsleep(struct srvparam *srv, int n){ + if(onloopfunc && onloopfunc()) sockpoll(&srv->so, srv->so.state, NULL, 0, n); + else usleep(SLEEPTIME * n); +} + static int srvspawn(struct srvstart *s, SOCKET client_sock){ struct srvparam *srv = &s->srv; struct clientparam *defparam = &s->defparam; @@ -308,7 +315,7 @@ static int srvspawn(struct srvstart *s, SOCKET client_sock){ srv->so._closesocket(srv->so.state, client_sock); defparam->res = 21; if(!srv->silent)dolog(defparam, (unsigned char *)"Memory Allocation Failed"); - usleep(SLEEPTIME); + srvsleep(srv, 1); return 1; }; if(!reused){ diff --git a/src/maintcp.c b/src/maintcp.c index 60cc311..8210eab 100644 --- a/src/maintcp.c +++ b/src/maintcp.c @@ -111,7 +111,7 @@ static int tcpnext(struct srvstart *s, SOCKET *client, int *nlog){ case WSAEMFILE: case WSAENOBUFS: case WSAENETDOWN: - usleep(SLEEPTIME * 10); + srvsleep(srv, 10); break; case WSAEINTR: error = 1; @@ -135,7 +135,7 @@ static int tcpnext(struct srvstart *s, SOCKET *client, int *nlog){ #ifdef ENOMEM case ENOMEM: #endif - usleep(SLEEPTIME * 10); + srvsleep(srv, 10); break; default: