mirror of
https://github.com/3proxy/3proxy.git
synced 2026-11-05 09:25:49 +08:00
splice() pipes closed with fdclose(), the loop forgetting them first
sockmap waits on its splice() pipes as on its sockets, and on an event loop a pipe waited on is registered there like a socket. They were closed with close(), past the socket functions, so the loop kept the registration of a closed descriptor, which epoll and kqueue drop on the close: a socket given the same number later was taken for it, never registered, and its fiber waited on it forever. fdclose() tells the loop first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7b873b80b1
commit
9cdac1cb60
10
src/common.c
10
src/common.c
@ -492,6 +492,16 @@ struct sockfuncs so = {
|
||||
def_closesocket
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
/* close() of a descriptor a fiber may have waited on, a pipe of splice():
|
||||
its loop forgets it first, or a socket given the same number later would
|
||||
be taken for it, and never registered. */
|
||||
int fdclose(int fd){
|
||||
if(fiberclosefunc) fiberclosefunc(fd);
|
||||
return close(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Whether s, found readable, is: data or its end there. A fiber's wait
|
||||
may answer with what a socket was reported ready for, until an
|
||||
operation finds it not to be: whatever takes readability for an end,
|
||||
|
||||
@ -393,10 +393,10 @@ void releaseparam(struct clientparam * param) {
|
||||
param->clibuf = param->clibufdata;
|
||||
param->srvbuf = param->srvbufdata;
|
||||
#ifdef WITHSPLICE
|
||||
if(param->pipecli[0] >= 0) close(param->pipecli[0]);
|
||||
if(param->pipecli[1] >= 0) close(param->pipecli[1]);
|
||||
if(param->pipesrv[0] >= 0) close(param->pipesrv[0]);
|
||||
if(param->pipesrv[1] >= 0) close(param->pipesrv[1]);
|
||||
if(param->pipecli[0] >= 0) fdclose(param->pipecli[0]);
|
||||
if(param->pipecli[1] >= 0) fdclose(param->pipecli[1]);
|
||||
if(param->pipesrv[0] >= 0) fdclose(param->pipesrv[0]);
|
||||
if(param->pipesrv[1] >= 0) fdclose(param->pipesrv[1]);
|
||||
param->pipecli[0] = param->pipecli[1] = param->pipesrv[0] = param->pipesrv[1] = -1;
|
||||
#endif
|
||||
/* Not shut down on Windows: there shutting down receiving resets the
|
||||
|
||||
@ -337,6 +337,9 @@ extern int (*fiberpollfunc)(struct pollfd *fds, unsigned nfds, int timeout);
|
||||
extern void (*fiberblockfunc)(SOCKET s, short events);
|
||||
extern void (*fiberclosefunc)(SOCKET s);
|
||||
int sockreadable(SOCKET s);
|
||||
#ifndef _WIN32
|
||||
int fdclose(int fd);
|
||||
#endif
|
||||
void nonblock(SOCKET sock);
|
||||
int sysresolves(int mode);
|
||||
int acceptagain(void);
|
||||
|
||||
@ -1009,13 +1009,13 @@ CLEANRET:
|
||||
/* empty pipes stay with the connection for its next mapping; one still
|
||||
holding data, left by an error or a timeout, cannot be used again */
|
||||
if(inclientpipe && pipecli[0] >= 0){
|
||||
close(pipecli[0]);
|
||||
close(pipecli[1]);
|
||||
fdclose(pipecli[0]);
|
||||
fdclose(pipecli[1]);
|
||||
pipecli[0] = pipecli[1] = -1;
|
||||
}
|
||||
if(inserverpipe && pipesrv[0] >= 0){
|
||||
close(pipesrv[0]);
|
||||
close(pipesrv[1]);
|
||||
fdclose(pipesrv[0]);
|
||||
fdclose(pipesrv[1]);
|
||||
pipesrv[0] = pipesrv[1] = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user