unix: improve OOM handling in poll, tcp and udp

Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
This commit is contained in:
Juan José Arboleda 2025-04-26 15:43:16 -05:00
parent a1692f7646
commit 70f6b40548
3 changed files with 34 additions and 9 deletions

View File

@ -119,6 +119,7 @@ int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
uv__io_t** watchers;
uv__io_t* w;
int events;
int r;
assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT |
UV_PRIORITIZED)) == 0);
@ -146,7 +147,10 @@ int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
if (pevents & UV_DISCONNECT)
events |= UV__POLLRDHUP;
uv__io_start(handle->loop, &handle->io_watcher, events);
r = uv__io_start(handle->loop, &handle->io_watcher, events);
if (r)
return r;
uv__handle_start(handle);
handle->poll_cb = poll_cb;

View File

@ -333,6 +333,9 @@ int uv__tcp_connect(uv_connect_t* req,
}
out:
err = uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
if (err)
return err;
uv__req_init(handle->loop, req, UV_CONNECT);
req->cb = cb;
@ -340,8 +343,6 @@ out:
uv__queue_init(&req->queue);
handle->connect_req = req;
uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
if (handle->delayed_error)
uv__io_feed(handle->loop, &handle->io_watcher);
@ -445,7 +446,14 @@ int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
/* Start listening for connections. */
tcp->io_watcher.cb = uv__server_io;
uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
err = uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
if (err) {
/* clean things up */
uv__queue_remove(&tcp->handle_queue);
uv__close(tcp->io_watcher.fd);
tcp->io_watcher.fd = -1;
return err;
}
return 0;
}

View File

@ -579,8 +579,8 @@ int uv__udp_send(uv_udp_send_t* req,
const struct sockaddr* addr,
unsigned int addrlen,
uv_udp_send_cb send_cb) {
int err;
int empty_queue;
int err = 0;
assert(nbufs > 0);
@ -629,12 +629,22 @@ int uv__udp_send(uv_udp_send_t* req,
* write.
*/
if (!uv__queue_empty(&handle->write_queue))
uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
err = uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
} else {
uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
err = uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
}
return 0;
if (err) {
if (req->bufs != req->bufsml)
uv__free(req->bufs); /* Free the allocated bufs */
req->bufs = NULL;
uv__queue_remove(&req->queue); /* Remove from the write queue */
uv__req_unregister(handle->loop); /* The req is not in the queue */
uv__handle_stop(handle); /* The uv__io_start failed, undo handle op */
}
return err;
}
@ -1223,7 +1233,10 @@ int uv__udp_recv_start(uv_udp_t* handle,
handle->alloc_cb = alloc_cb;
handle->recv_cb = recv_cb;
uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
err = uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
if (err)
return err;
uv__handle_start(handle);
return 0;