fix: uasync epoll event ordering + test_uasync_socket_race fix

This commit is contained in:
evgeny committed 2026-07-29 11:10:55 +03:00
1 parent b7988f0ef8
commit ce5a84da24
8 files changed
+479 -196

No files matched your search

+26 -26
View File
@@ -941,14 +941,7 @@ static void process_epoll_events(struct UASYNC* ua, struct epoll_event* events,
socket_t_callback_t local_read_sock = node->read_cbk_sock;
socket_t_callback_t local_write_sock = node->write_cbk_sock;
/* Check for error conditions first */
if (events[i].events & (EPOLLERR | EPOLLHUP)) {
if (local_except) {
local_except(local_fd, local_ud);
}
}
/* Read readiness - use appropriate callback based on socket type */
/* Read readiness BEFORE error — avoid losing data on combined IN+HUP events */
if (events[i].events & EPOLLIN) {
if (local_type == SOCKET_NODE_TYPE_SOCK) {
if (local_read_sock) {
@@ -961,7 +954,7 @@ static void process_epoll_events(struct UASYNC* ua, struct epoll_event* events,
}
}
/* Write readiness - use appropriate callback based on socket type */
/* Write readiness BEFORE error — flush pending writes before handling HUP */
if (events[i].events & EPOLLOUT) {
if (local_type == SOCKET_NODE_TYPE_SOCK) {
if (local_write_sock) {
@@ -973,6 +966,13 @@ static void process_epoll_events(struct UASYNC* ua, struct epoll_event* events,
}
}
}
/* Check for error conditions LAST — I/O handlers drain/process data first */
if (events[i].events & (EPOLLERR | EPOLLHUP)) {
if (local_except) {
local_except(local_fd, local_ud);
}
}
}
}
#endif
@@ -1238,22 +1238,7 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
}
if (!node) continue; // Socket may have been removed
/* Check for error conditions first */
if (ua->poll_fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
/* Treat as exceptional condition */
if (node->except_cbk) {
node->except_cbk(node->fd, node->user_data);
}
}
/* Exceptional data (out-of-band) */
if (ua->poll_fds[i].revents & POLLPRI) {
if (node->except_cbk) {
node->except_cbk(node->fd, node->user_data);
}
}
/* Read readiness - use appropriate callback based on socket type */
/* Read readiness BEFORE error — avoid losing data on combined IN+ERR/HUP events */
if (ua->poll_fds[i].revents & POLLIN) {
if (node->type == SOCKET_NODE_TYPE_SOCK) {
if (node->read_cbk_sock) {
@@ -1266,7 +1251,7 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
}
}
/* Write readiness - use appropriate callback based on socket type */
/* Write readiness BEFORE error — flush pending writes before handling HUP */
if (ua->poll_fds[i].revents & POLLOUT) {
if (node->type == SOCKET_NODE_TYPE_SOCK) {
if (node->write_cbk_sock) {
@@ -1278,6 +1263,21 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
}
}
}
/* Check for error conditions LAST — I/O handlers drain/process data first */
if (ua->poll_fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
/* Treat as exceptional condition */
if (node->except_cbk) {
node->except_cbk(node->fd, node->user_data);
}
}
/* Exceptional data (out-of-band) */
if (ua->poll_fds[i].revents & POLLPRI) {
if (node->except_cbk) {
node->except_cbk(node->fd, node->user_data);
}
}
}
}
#endif