summaryrefslogtreecommitdiff
path: root/src/fdevent_fdnode.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2021-06-29 10:08:52 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2023-05-03 23:11:34 -0400
commit8e4718ac0bc57906c620146a590b6285a211d00a (patch)
treeef500da1027e5dcb4de2fd4a9a73ff17057ba76d /src/fdevent_fdnode.c
parent635560092fbe8a6bdbf93c0781bc65032da25135 (diff)
downloadlighttpd-git-8e4718ac0bc57906c620146a590b6285a211d00a.tar.gz
[core] _WIN32 alternative fdarray for Windows
_WIN32 SOCKET (long long unsigned) handles are assigned differently from how POSIX allocates file descriptors (lowest number available). On _WIN32, the SOCKET descriptor should not be used to index an array of (fdnode *), so this commit provides an alternative method to store (fdnode *) for use by select() and by WSAPoll(). select(): commonly used unix select() idioms may be incorrect on _WIN32 https://devblogs.microsoft.com/oldnewthing/20221102-00/?p=107343 https://devblogs.microsoft.com/oldnewthing/20161221-00/?p=94985 WSAPoll(): https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll As of Windows 10 version 2004, when a TCP socket fails to connect, (POLLHUP | POLLERR | POLLWRNORM) is indicated. (note: this was broken in WSAPoll() in all earlier Windows versions)
Diffstat (limited to 'src/fdevent_fdnode.c')
-rw-r--r--src/fdevent_fdnode.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/fdevent_fdnode.c b/src/fdevent_fdnode.c
index 4dbb3878..f498c57b 100644
--- a/src/fdevent_fdnode.c
+++ b/src/fdevent_fdnode.c
@@ -25,7 +25,12 @@ fdnode_free (fdnode *fdn)
fdnode *
fdevent_register (fdevents *ev, int fd, fdevent_handler handler, void *ctx)
{
+ #ifdef _WIN32
+ fdnode *fdn = fdnode_init();
+ ev->fdarray[(fdn->fda_ndx = ev->count++)] = fdn;
+ #else
fdnode *fdn = ev->fdarray[fd] = fdnode_init();
+ #endif
fdn->handler = handler;
fdn->fd = fd;
fdn->ctx = ctx;
@@ -34,11 +39,26 @@ fdevent_register (fdevents *ev, int fd, fdevent_handler handler, void *ctx)
return fdn;
}
+#ifdef _WIN32
+#define fdevent_fdarray_slot(ev,fdn) &(ev)->fdarray[(fdn)->fda_ndx]
+#else
+#define fdevent_fdarray_slot(ev,fdn) &(ev)->fdarray[(fdn)->fd]
+#endif
+
void
fdevent_unregister (fdevents *ev, fdnode *fdn)
{
- fdnode **fdn_slot = &ev->fdarray[fdn->fd];
+ fdnode **fdn_slot = fdevent_fdarray_slot(ev, fdn);
if ((uintptr_t)*fdn_slot & 0x3) return; /*(should not happen)*/
+ #ifdef _WIN32
+ if (--ev->count != fdn->fda_ndx) {
+ /* compact fdarray; move element in last slot */
+ fdnode **fdn_last = &ev->fdarray[ev->count];
+ *fdn_slot = *fdn_last;
+ ((fdnode *)((uintptr_t)*fdn_slot & ~0x3))->fda_ndx = fdn->fda_ndx;
+ fdn_slot = fdn_last;
+ }
+ #endif
*fdn_slot = NULL;
fdnode_free(fdn);
}
@@ -46,7 +66,7 @@ fdevent_unregister (fdevents *ev, fdnode *fdn)
void
fdevent_sched_close (fdevents *ev, fdnode *fdn)
{
- fdnode **fdn_slot = &ev->fdarray[fdn->fd];
+ fdnode **fdn_slot = fdevent_fdarray_slot(ev, fdn);
if ((uintptr_t)*fdn_slot & 0x3) return;
*fdn_slot = (fdnode *)((uintptr_t)fdn | 0x3);
fdn->handler = (fdevent_handler)NULL;