summaryrefslogtreecommitdiff
path: root/src/fdevent.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2017-10-21 12:20:27 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2017-10-21 12:34:17 -0400
commit168f67a1b1ea17e3fa0a6b18bbd092e6b21765ee (patch)
tree97e2ddba5d9f3e35becc5959f44d2cf15b1724df /src/fdevent.c
parentcddc4814114a6d9dd3156da5a1ae3ea61020aecb (diff)
downloadlighttpd-git-168f67a1b1ea17e3fa0a6b18bbd092e6b21765ee.tar.gz
[core] perf: more efficient fdevent_sched_run()
perf: more efficient fdevent_sched_run() over fds pending close
Diffstat (limited to 'src/fdevent.c')
-rw-r--r--src/fdevent.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/src/fdevent.c b/src/fdevent.c
index 232cfead..2300821b 100644
--- a/src/fdevent.c
+++ b/src/fdevent.c
@@ -46,7 +46,6 @@ fdevents *fdevent_init(server *srv, size_t maxfds, int type) {
return NULL;
}
ev->maxfds = maxfds;
- ev->highfd = -1;
switch(type) {
case FDEVENT_HANDLER_POLL:
@@ -119,7 +118,10 @@ void fdevent_free(fdevents *ev) {
if (ev->free) ev->free(ev);
for (i = 0; i < ev->maxfds; i++) {
- if (ev->fdarray[i] > (fdnode *)0x2) free(ev->fdarray[i]);
+ /* (fdevent_sched_run() should already have been run,
+ * but take reasonable precautions anyway) */
+ if (ev->fdarray[i])
+ free((fdnode *)((uintptr_t)ev->fdarray[i] & ~0x3));
}
free(ev->fdarray);
@@ -165,6 +167,7 @@ int fdevent_unregister(fdevents *ev, int fd) {
if (!ev) return 0;
fdn = ev->fdarray[fd];
+ if ((uintptr_t)fdn & 0x3) return 0; /*(should not happen)*/
fdnode_free(fdn);
@@ -174,22 +177,29 @@ int fdevent_unregister(fdevents *ev, int fd) {
}
void fdevent_sched_close(fdevents *ev, int fd, int issock) {
+ fdnode *fdn;
if (!ev) return;
- ev->fdarray[fd] = (issock ? (fdnode *)0x1 : (fdnode *)0x2);
- if (ev->highfd < fd) ev->highfd = fd;
+ fdn = ev->fdarray[fd];
+ if ((uintptr_t)fdn & 0x3) return;
+ ev->fdarray[fd] = (fdnode *)((uintptr_t)fdn | (issock ? 0x1 : 0x2));
+ fdn->ctx = ev->pendclose;
+ ev->pendclose = fdn;
}
void fdevent_sched_run(server *srv, fdevents *ev) {
- const int highfd = ev->highfd;
- for (int fd = 0; fd <= highfd; ++fd) {
- fdnode * const fdn = ev->fdarray[fd];
- int rc;
- if (!((uintptr_t)fdn & 0x3)) continue;
+ for (fdnode *fdn = ev->pendclose; fdn; ) {
+ int fd, rc;
+ fdnode *fdn_tmp;
#ifdef _WIN32
- if (fdn == (fdnode *)0x1) {
+ rc = (uintptr_t)fdn & 0x3;
+ #endif
+ fdn = (fdnode *)((uintptr_t)fdn & ~0x3);
+ fd = fdn->fd;
+ #ifdef _WIN32
+ if (rc == 0x1) {
rc = closesocket(fd);
}
- else if (fdn == (fdnode *)0x2) {
+ else if (rc == 0x2) {
rc = close(fd);
}
#else
@@ -199,16 +209,22 @@ void fdevent_sched_run(server *srv, fdevents *ev) {
if (0 != rc) {
log_error_write(srv, __FILE__, __LINE__, "sds", "close failed ", fd, strerror(errno));
}
+ else {
+ --srv->cur_fds;
+ }
+ fdn_tmp = fdn;
+ fdn = (fdnode *)fdn->ctx; /* next */
+ /*(fdevent_unregister)*/
+ fdnode_free(fdn_tmp);
ev->fdarray[fd] = NULL;
- --srv->cur_fds;
}
- ev->highfd = -1;
+ ev->pendclose = NULL;
}
void fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) {
if (-1 == fd) return;
- if (ev->fdarray[fd] <= (fdnode *)0x2) return;
+ if ((uintptr_t)ev->fdarray[fd] & 0x3) return;
if (ev->event_del) *fde_ndx = ev->event_del(ev, *fde_ndx, fd);
ev->fdarray[fd]->events = 0;