async: Try to avoid race conditions when adding/removing fds

This commit is contained in:
2026-06-03 23:53:15 +02:00
parent 0ab1d2af96
commit a240bb7e48
2 changed files with 17 additions and 8 deletions
+16 -6
View File
@@ -137,20 +137,20 @@ static int async_add_to_queue(evt_listen_t *evt) {
return 0; return 0;
} }
static int async_exec(evt_listen_t *evt, async_evt_t r_events) { static int async_exec_cb(evt_listen_t *evt, async_evt_t r_events, void (**cb)(void *)) {
int ret, e = errno; int ret, e = errno;
if (r_events & evt->events) { if (r_events & evt->events) {
// specified event(s) occurred // specified event(s) occurred
if (!(evt->flags & ASYNC_IGNORE_PENDING) && evt->socket && !sock_has_pending(evt->socket, 0)) { if (!(evt->flags & ASYNC_IGNORE_PENDING) && evt->socket && !sock_has_pending(evt->socket, 0)) {
evt->err_cb(evt->arg); *cb = evt->err_cb;
ret = 0; ret = 0;
} else { } else {
evt->cb(evt->arg); *cb = evt->cb;
ret = (evt->flags & ASYNC_KEEP) ? 1 : 0; ret = (evt->flags & ASYNC_KEEP) ? 1 : 0;
} }
} else if (r_events & (POLLERR | POLLHUP | POLLNVAL)) { } else if (r_events & (POLLERR | POLLHUP | POLLNVAL)) {
// error occurred // error occurred
evt->err_cb(evt->arg); *cb = evt->err_cb;
ret = 0; ret = 0;
} else { } else {
// no event occurred // no event occurred
@@ -161,6 +161,13 @@ static int async_exec(evt_listen_t *evt, async_evt_t r_events) {
return ret; return ret;
} }
static int async_exec(evt_listen_t *evt, async_evt_t r_events) {
void (*cb)(void *) = NULL;
const int ret = async_exec_cb(evt, r_events, &cb);
if (cb != NULL) cb(evt->arg);
return ret;
}
static int async_check(evt_listen_t *evt) { static int async_check(evt_listen_t *evt) {
struct pollfd fds[1] = {{ struct pollfd fds[1] = {{
.fd = evt->fd, .fd = evt->fd,
@@ -333,7 +340,6 @@ void async_thread(void) {
if (errno == EINTR) { if (errno == EINTR) {
// interrupt // interrupt
errno = 0; errno = 0;
continue;
} else { } else {
// other error // other error
critical("Unable to poll for events"); critical("Unable to poll for events");
@@ -345,7 +351,8 @@ void async_thread(void) {
evt_listen_t *evt = events[i].data.ptr; evt_listen_t *evt = events[i].data.ptr;
if (!list_contains(local, &evt)) continue; if (!list_contains(local, &evt)) continue;
if (async_exec(evt, async_e2a(events[i].events)) == 0) { void (*cb)(void *) = NULL;
if (async_exec_cb(evt, async_e2a(events[i].events), &cb) == 0) {
logger_set_prefix(""); logger_set_prefix("");
if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, evt->fd, NULL) == -1) { if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, evt->fd, NULL) == -1) {
if (errno == EBADF || errno == ENOENT || errno == EPERM) { if (errno == EBADF || errno == ENOENT || errno == EPERM) {
@@ -363,7 +370,10 @@ void async_thread(void) {
return; return;
} }
if (cb != NULL) cb(evt->arg);
free(evt); free(evt);
} else {
if (cb != NULL) cb(evt->arg);
} }
logger_set_prefix(""); logger_set_prefix("");
} }
+1 -2
View File
@@ -127,13 +127,12 @@ static void proxy_chunk_next_cb(chunk_ctx_t *ctx) {
} }
static void proxy_chunk_err_cb(chunk_ctx_t *ctx) { static void proxy_chunk_err_cb(chunk_ctx_t *ctx) {
ctx->client->c_keep_alive = 0;
proxy_close(ctx->client->proxy); proxy_close(ctx->client->proxy);
proxy_unlock_ctx(ctx->client->proxy); proxy_unlock_ctx(ctx->client->proxy);
ctx->client->proxy = NULL; ctx->client->proxy = NULL;
request_complete(ctx->client); request_complete(ctx->client);
handle_request(ctx->client); tcp_close(ctx->client);
} }
static int proxy_handler_2(client_ctx_t *ctx) { static int proxy_handler_2(client_ctx_t *ctx) {