diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2021-06-29 10:08:52 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2023-05-03 23:11:34 -0400 |
commit | 8e4718ac0bc57906c620146a590b6285a211d00a (patch) | |
tree | ef500da1027e5dcb4de2fd4a9a73ff17057ba76d /src/fdevent_fdnode.c | |
parent | 635560092fbe8a6bdbf93c0781bc65032da25135 (diff) | |
download | lighttpd-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.c | 24 |
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; |