From e0a69327048af34add7acf04e61b0fe2f46736a2 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 25 Oct 2026 21:27:21 +0300 Subject: [PATCH] Event loops: the callbacks' pipes emptied before sockmap() takes over On a reload the relay of the callbacks gives the connection back to sockmap(), which knows nothing of what its pipes hold, nor of how much of a body of known length has already gone through: what was in a pipe would have come out of order, and the whole length of a body been read again, into what follows it. The pipes are emptied first, the relay going on meanwhile, and the length left of a body is the one sockmap() is given. Co-Authored-By: Claude Opus 5.5 --- src/mainloop.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mainloop.c b/src/mainloop.c index 009c8ae..1ff0a22 100644 --- a/src/mainloop.c +++ b/src/mainloop.c @@ -604,8 +604,14 @@ static int cbmaprun(struct cbmap *m){ int round, moved = 0; /* a reload: sockmap() takes the connection back, which has it go by - the newest configuration's rules, or ends it */ - if(param->version < runconf->version) return cbmapend(m, -2); + the newest configuration's rules, or ends it. It knows nothing of + what the pipes hold: they are emptied first. What is left of a body + is what it is to move. */ + if(param->version < runconf->version && !m->way[0].inpipe && !m->way[1].inpipe){ + if(param->waitclient64) param->waitclient64 = m->way[0].left; + if(param->waitserver64) param->waitserver64 = m->way[1].left; + return cbmapend(m, -2); + } for(round = 0; round < CBROUNDS; round++){ int progress = cbway(m, &m->way[0]) | cbway(m, &m->way[1]); int end = !m->halfclose && (m->term_r[0] || m->term_r[1]);