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
|
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
|
/* 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
|
may answer with what a socket was reported ready for, until an
|
||||||
operation finds it not to be: whatever takes readability for an end,
|
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->clibuf = param->clibufdata;
|
||||||
param->srvbuf = param->srvbufdata;
|
param->srvbuf = param->srvbufdata;
|
||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
if(param->pipecli[0] >= 0) close(param->pipecli[0]);
|
if(param->pipecli[0] >= 0) fdclose(param->pipecli[0]);
|
||||||
if(param->pipecli[1] >= 0) close(param->pipecli[1]);
|
if(param->pipecli[1] >= 0) fdclose(param->pipecli[1]);
|
||||||
if(param->pipesrv[0] >= 0) close(param->pipesrv[0]);
|
if(param->pipesrv[0] >= 0) fdclose(param->pipesrv[0]);
|
||||||
if(param->pipesrv[1] >= 0) close(param->pipesrv[1]);
|
if(param->pipesrv[1] >= 0) fdclose(param->pipesrv[1]);
|
||||||
param->pipecli[0] = param->pipecli[1] = param->pipesrv[0] = param->pipesrv[1] = -1;
|
param->pipecli[0] = param->pipecli[1] = param->pipesrv[0] = param->pipesrv[1] = -1;
|
||||||
#endif
|
#endif
|
||||||
/* Not shut down on Windows: there shutting down receiving resets the
|
/* 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 (*fiberblockfunc)(SOCKET s, short events);
|
||||||
extern void (*fiberclosefunc)(SOCKET s);
|
extern void (*fiberclosefunc)(SOCKET s);
|
||||||
int sockreadable(SOCKET s);
|
int sockreadable(SOCKET s);
|
||||||
|
#ifndef _WIN32
|
||||||
|
int fdclose(int fd);
|
||||||
|
#endif
|
||||||
void nonblock(SOCKET sock);
|
void nonblock(SOCKET sock);
|
||||||
int sysresolves(int mode);
|
int sysresolves(int mode);
|
||||||
int acceptagain(void);
|
int acceptagain(void);
|
||||||
|
|||||||
@ -1009,13 +1009,13 @@ CLEANRET:
|
|||||||
/* empty pipes stay with the connection for its next mapping; one still
|
/* 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 */
|
holding data, left by an error or a timeout, cannot be used again */
|
||||||
if(inclientpipe && pipecli[0] >= 0){
|
if(inclientpipe && pipecli[0] >= 0){
|
||||||
close(pipecli[0]);
|
fdclose(pipecli[0]);
|
||||||
close(pipecli[1]);
|
fdclose(pipecli[1]);
|
||||||
pipecli[0] = pipecli[1] = -1;
|
pipecli[0] = pipecli[1] = -1;
|
||||||
}
|
}
|
||||||
if(inserverpipe && pipesrv[0] >= 0){
|
if(inserverpipe && pipesrv[0] >= 0){
|
||||||
close(pipesrv[0]);
|
fdclose(pipesrv[0]);
|
||||||
close(pipesrv[1]);
|
fdclose(pipesrv[1]);
|
||||||
pipesrv[0] = pipesrv[1] = -1;
|
pipesrv[0] = pipesrv[1] = -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user