Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions packages/bun-usockets/src/eventing/libuv.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@ int us_internal_libuv_peer_reset_probe(LIBUS_SOCKET_DESCRIPTOR fd) {
}

static struct us_socket_t *us_internal_poll_cb_adopted_socket(struct us_poll_t *wp) {
struct us_socket_t *s = (struct us_socket_t *)wp;
if (s->flags.adopted && s->prev) {
s = s->prev;
}
return s;
return us_internal_socket_follow_adopted((struct us_socket_t *)wp);
}

static int us_internal_poll_cb_socket_is_probeable(struct us_poll_t *wp) {
Expand Down
15 changes: 15 additions & 0 deletions packages/bun-usockets/src/internal/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,21 @@ struct us_socket_t {
_Static_assert(sizeof(struct us_socket_flags) == 1, "us_socket_flags grew");
#endif

/* us_socket_adopt relocates a socket whose ext grows and retires the old block
* (is_closed + adopted, prev -> replacement; freed by the outermost tick's
* us_internal_free_closed_sockets, so it is still readable mid-dispatch). A
* callback may adopt more than once before returning, retiring each block in
* turn, so walk the whole chain rather than one link: one link can land on a
* block that is itself retired. The walk ends on the live block, which never
* has adopted set (the copy is taken before the source is flagged). Tolerates
* NULL, which callbacks may return. */
static inline struct us_socket_t *us_internal_socket_follow_adopted(struct us_socket_t *s) {
while (s && s->flags.adopted && s->prev) {
s = s->prev;
}
return s;
}

struct us_connecting_socket_t {
alignas(LIBUS_EXT_ALIGNMENT) struct addrinfo_request *addrinfo_req;
struct us_socket_group_t *group;
Expand Down
16 changes: 4 additions & 12 deletions packages/bun-usockets/src/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,9 +555,7 @@ void us_internal_dispatch_ready_poll(struct us_poll_t *p, int error, int eof, in
us_dispatch_open(s, 0, bsd_addr_get_ip(&addr), bsd_addr_get_ip_length(&addr));
}
/* After socket adoption, track the new socket; the old one becomes invalid */
if(s && s->flags.adopted && s->prev) {
s = s->prev;
}
s = us_internal_socket_follow_adopted(s);

/* When the kernel deferred the accept until data arrived (TCP_DEFER_ACCEPT
* on Linux, SO_ACCEPTFILTER on FreeBSD), the request/ClientHello is already
Expand All @@ -583,9 +581,7 @@ void us_internal_dispatch_ready_poll(struct us_poll_t *p, int error, int eof, in
/* We should only use s, no p after this point */
struct us_socket_t *s = (struct us_socket_t *) p;
/* After socket adoption, track the new socket; the old one becomes invalid */
if(s && s->flags.adopted && s->prev) {
s = s->prev;
}
s = us_internal_socket_follow_adopted(s);
/* The group can change after calling a callback but the loop is always the same */
struct us_loop_t* loop = s->group->loop;
if (events & LIBUS_SOCKET_WRITABLE && !error) {
Expand All @@ -601,9 +597,7 @@ void us_internal_dispatch_ready_poll(struct us_poll_t *p, int error, int eof, in

s = s->ssl ? us_internal_ssl_on_writable(s) : us_dispatch_writable(s);
/* After socket adoption, track the new socket; the old one becomes invalid */
if(s && s->flags.adopted && s->prev) {
s = s->prev;
}
s = us_internal_socket_follow_adopted(s);

if (!s || us_socket_is_closed(s)) {
return;
Expand Down Expand Up @@ -724,9 +718,7 @@ void us_internal_dispatch_ready_poll(struct us_poll_t *p, int error, int eof, in
s = s->ssl ? us_internal_ssl_on_data(s, loop->data.recv_buf + LIBUS_RECV_BUFFER_PADDING, length)
: us_dispatch_data(s, loop->data.recv_buf + LIBUS_RECV_BUFFER_PADDING, length);
/* After socket adoption, track the new socket; the old one becomes invalid */
if(s && s->flags.adopted && s->prev) {
s = s->prev;
}
s = us_internal_socket_follow_adopted(s);
read_any = 1;
// loop->num_ready_polls isn't accessible on Windows.
#ifndef WIN32
Expand Down