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 <noreply@anthropic.com>
This commit is contained in:
Vladimir Dubrovin 2026-10-28 11:52:20 +03:00
parent 9025c8483f
commit 055d274f50
2 changed files with 10 additions and 3 deletions

View File

@ -259,6 +259,13 @@ void * threadfunc (void *p) {
/* A thread for the client, client_sock for TCP, or a fiber of an event /* 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. */ 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){ static int srvspawn(struct srvstart *s, SOCKET client_sock){
struct srvparam *srv = &s->srv; struct srvparam *srv = &s->srv;
struct clientparam *defparam = &s->defparam; 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); srv->so._closesocket(srv->so.state, client_sock);
defparam->res = 21; defparam->res = 21;
if(!srv->silent)dolog(defparam, (unsigned char *)"Memory Allocation Failed"); if(!srv->silent)dolog(defparam, (unsigned char *)"Memory Allocation Failed");
usleep(SLEEPTIME); srvsleep(srv, 1);
return 1; return 1;
}; };
if(!reused){ if(!reused){

View File

@ -111,7 +111,7 @@ static int tcpnext(struct srvstart *s, SOCKET *client, int *nlog){
case WSAEMFILE: case WSAEMFILE:
case WSAENOBUFS: case WSAENOBUFS:
case WSAENETDOWN: case WSAENETDOWN:
usleep(SLEEPTIME * 10); srvsleep(srv, 10);
break; break;
case WSAEINTR: case WSAEINTR:
error = 1; error = 1;
@ -135,7 +135,7 @@ static int tcpnext(struct srvstart *s, SOCKET *client, int *nlog){
#ifdef ENOMEM #ifdef ENOMEM
case ENOMEM: case ENOMEM:
#endif #endif
usleep(SLEEPTIME * 10); srvsleep(srv, 10);
break; break;
default: default: