mirror of
https://github.com/3proxy/3proxy.git
synced 2026-11-05 09:25:49 +08:00
Event loops: readiness asked again of the system in one poll()
A fiber's wait asks the system again what each socket was reported ready for and answered with once already: one poll() for each of them, two for an HTTP connection kept alive waiting on both of its sides. They are asked all at once now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5ed8e8cee4
commit
f991edbb3a
@ -318,30 +318,46 @@ static void fiberclosed(SOCKET s){
|
|||||||
operation past the socket functions, and the system is asked. */
|
operation past the socket functions, and the system is asked. */
|
||||||
static int fiberpollregs(struct looper *lp, struct pollfd *fds, unsigned nfds, int timeout){
|
static int fiberpollregs(struct looper *lp, struct pollfd *fds, unsigned nfds, int timeout){
|
||||||
struct sockreg *ownregs[FIBERWAITS], **regs = ownregs;
|
struct sockreg *ownregs[FIBERWAITS], **regs = ownregs;
|
||||||
|
struct pollfd ownask[FIBERWAITS], *ask = ownask;
|
||||||
|
unsigned char ownasked[FIBERWAITS], *asked = ownasked;
|
||||||
struct fiberwait w;
|
struct fiberwait w;
|
||||||
unsigned i;
|
unsigned i, nask = 0;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if(nfds > FIBERWAITS && !(regs = malloc(nfds * sizeof(*regs)))) return -1;
|
if(nfds > FIBERWAITS && (!(regs = malloc(nfds * sizeof(*regs))) ||
|
||||||
|
!(ask = malloc(nfds * sizeof(*ask))) || !(asked = malloc(nfds)))){
|
||||||
|
res = -1;
|
||||||
|
goto DONE;
|
||||||
|
}
|
||||||
for(i = 0; i < nfds; i++){
|
for(i = 0; i < nfds; i++){
|
||||||
short want = fds[i].events & (POLLIN | POLLOUT), have;
|
short want = fds[i].events & (POLLIN | POLLOUT);
|
||||||
|
|
||||||
fds[i].revents = 0;
|
fds[i].revents = 0;
|
||||||
regs[i] = NULL;
|
regs[i] = NULL;
|
||||||
|
asked[i] = 0;
|
||||||
if(fds[i].fd == INVALID_SOCKET || (int)fds[i].fd < 0) continue;
|
if(fds[i].fd == INVALID_SOCKET || (int)fds[i].fd < 0) continue;
|
||||||
if(!(regs[i] = sockreg(lp, fds[i].fd))){
|
if(!(regs[i] = sockreg(lp, fds[i].fd))){
|
||||||
res = -1;
|
res = -1;
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
have = regs[i]->ready & (want | POLLERR | POLLHUP);
|
/* to be asked of the system: all of them at once */
|
||||||
if(have & regs[i]->stale){
|
if(regs[i]->ready & (want | POLLERR | POLLHUP) & regs[i]->stale){
|
||||||
struct pollfd p;
|
ask[nask].fd = fds[i].fd;
|
||||||
|
ask[nask].events = POLLIN | POLLOUT;
|
||||||
|
ask[nask].revents = 0;
|
||||||
|
nask++;
|
||||||
|
asked[i] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* failing, what was known stays */
|
||||||
|
if(nask && poll(ask, nask, 0) < 0) memset(asked, 0, nfds);
|
||||||
|
for(i = 0, nask = 0; i < nfds; i++) if(regs[i]){
|
||||||
|
short have;
|
||||||
|
|
||||||
|
if(asked[i]){
|
||||||
short was = regs[i]->ready;
|
short was = regs[i]->ready;
|
||||||
|
|
||||||
p.fd = fds[i].fd;
|
regs[i]->ready = ask[nask++].revents & READYBITS;
|
||||||
p.events = POLLIN | POLLOUT;
|
|
||||||
p.revents = 0;
|
|
||||||
if(poll(&p, 1, 0) >= 0) regs[i]->ready = p.revents & READYBITS;
|
|
||||||
#if defined LOOP_KQUEUE || defined LOOP_AFD
|
#if defined LOOP_KQUEUE || defined LOOP_AFD
|
||||||
/* poll() there tells a socket shut down for sending, by us,
|
/* poll() there tells a socket shut down for sending, by us,
|
||||||
as hung up, the loop does not: its end of reading is
|
as hung up, the loop does not: its end of reading is
|
||||||
@ -354,8 +370,8 @@ static int fiberpollregs(struct looper *lp, struct pollfd *fds, unsigned nfds, i
|
|||||||
if(was & ~regs[i]->ready)
|
if(was & ~regs[i]->ready)
|
||||||
loopagain(&lp->l, ®s[i]->io, was & ~regs[i]->ready);
|
loopagain(&lp->l, ®s[i]->io, was & ~regs[i]->ready);
|
||||||
regs[i]->stale = 0;
|
regs[i]->stale = 0;
|
||||||
have = regs[i]->ready & (want | POLLERR | POLLHUP);
|
|
||||||
}
|
}
|
||||||
|
have = regs[i]->ready & ((fds[i].events & (POLLIN | POLLOUT)) | POLLERR | POLLHUP);
|
||||||
fds[i].revents = have;
|
fds[i].revents = have;
|
||||||
if(have) res++;
|
if(have) res++;
|
||||||
}
|
}
|
||||||
@ -385,6 +401,8 @@ static int fiberpollregs(struct looper *lp, struct pollfd *fds, unsigned nfds, i
|
|||||||
}
|
}
|
||||||
DONE:
|
DONE:
|
||||||
if(regs != ownregs) free(regs);
|
if(regs != ownregs) free(regs);
|
||||||
|
if(ask != ownask) free(ask);
|
||||||
|
if(asked != ownasked) free(asked);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user