Compare commits

...

2 Commits

Author SHA1 Message Date
Jarred Sumner
c651e95119 Use one-shot epoll 2025-10-22 20:45:49 -07:00
Jarred Sumner
060d3d37a0 Fix kqueue readable & writable check 2025-10-22 20:45:38 -07:00

View File

@@ -299,8 +299,8 @@ void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout
// > Multiple events which trigger the filter do not result in multiple kevents being placed on the kqueue
// > Instead, the filter will aggregate the events into a single kevent struct
int events = 0
| ((filter & EVFILT_READ) ? LIBUS_SOCKET_READABLE : 0)
| ((filter & EVFILT_WRITE) ? LIBUS_SOCKET_WRITABLE : 0);
| ((filter == EVFILT_READ) ? LIBUS_SOCKET_READABLE : 0)
| ((filter == EVFILT_WRITE) ? LIBUS_SOCKET_WRITABLE : 0);
// Note: EV_ERROR only sets the error in data as part of changelist. Not in this call!
const int error = (flags & (EV_ERROR)) ? ((int)fflags || 1) : 0;
@@ -360,11 +360,11 @@ int kqueue_change(int kqfd, int fd, int old_events, int new_events, void *user_d
if(!is_readable && !is_writable) {
if(!(old_events & LIBUS_SOCKET_WRITABLE)) {
// if we are not reading or writing, we need to add writable to receive FIN
EV_SET64(&change_list[change_length++], fd, EVFILT_WRITE, EV_ADD, 0, 0, (uint64_t)(void*)user_data, 0, 0);
EV_SET64(&change_list[change_length++], fd, EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, (uint64_t)(void*)user_data, 0, 0);
}
} else if ((new_events & LIBUS_SOCKET_WRITABLE) != (old_events & LIBUS_SOCKET_WRITABLE)) {
/* Do they differ in writable? */
EV_SET64(&change_list[change_length++], fd, EVFILT_WRITE, (new_events & LIBUS_SOCKET_WRITABLE) ? EV_ADD : EV_DELETE, 0, 0, (uint64_t)(void*)user_data, 0, 0);
EV_SET64(&change_list[change_length++], fd, EVFILT_WRITE, (new_events & LIBUS_SOCKET_WRITABLE) ? (EV_ADD | EV_ONESHOT) : EV_DELETE, 0, 0, (uint64_t)(void*)user_data, 0, 0);
}
int ret;
do {
@@ -406,6 +406,13 @@ int us_poll_start_rc(struct us_poll_t *p, struct us_loop_t *loop, int events) {
// if we are disabling readable, we need to add the other events to detect EOF/HUP/ERR
events |= EPOLLRDHUP | EPOLLHUP | EPOLLERR;
}
// Make writable events one-shot, but keep readable events level-triggered
if (events & LIBUS_SOCKET_WRITABLE) {
events |= EPOLLONESHOT;
} else if (events & LIBUS_SOCKET_READABLE) {
// Ensure readable is level-triggered by explicitly removing EPOLLONESHOT
events &= ~EPOLLONESHOT;
}
event.events = events;
event.data.ptr = p;
int ret;
@@ -433,6 +440,13 @@ void us_poll_change(struct us_poll_t *p, struct us_loop_t *loop, int events) {
if(!(events & LIBUS_SOCKET_READABLE) && !(events & LIBUS_SOCKET_WRITABLE)) {
// if we are disabling readable, we need to add the other events to detect EOF/HUP/ERR
events |= EPOLLRDHUP | EPOLLHUP | EPOLLERR;
}
// Make writable events one-shot, but keep readable events level-triggered
if (events & LIBUS_SOCKET_WRITABLE) {
events |= EPOLLONESHOT;
} else if (events & LIBUS_SOCKET_READABLE) {
// Ensure readable is level-triggered by explicitly removing EPOLLONESHOT
events &= ~EPOLLONESHOT;
}
event.events = events;
event.data.ptr = p;