uSockets
uSockets copied to clipboard
Adopting/transferring in a file descriptor
For a project I've just been working on, I needed to be able to transfer in a socket that I created outside of uWebSockets/uSockets. I modified loop.c by moving the guts of the accept loop into a new function (us_socket_transfer) which is externally callable. The contents of the accept loop becomes just a call to this function, but if I create an accepted socket elsewhere in my program (transferred from another process, in my case) then I can call this function and the uWS::Loop "adopts" it. I haven't done extensive testing yet (and my code is just for an internal prototype so its not likely to become production code), but it seems to be working well. I thought I would suggest the change in case others might find it useful (I saw one issue mentioning inter-process socket transfers).
int us_socket_transfer(int client_fd, struct us_listen_socket_t *listen_socket, void *internal_addr)
{
struct bsd_addr_t *addr = (struct bsd_addr_t*)internal_addr;
struct bsd_addr_t bsd_addr;
if (addr == NULL)
{
addr = &bsd_addr;
if (bsd_remote_addr(client_fd, &bsd_addr) == -1)
return -1;
}
struct us_poll_t *accepted_p = us_create_poll(us_socket_context(0, &listen_socket->s)->loop, 0, sizeof(struct us_socket_t) - sizeof(struct us_poll_t) + listen_socket->socket_ext_size);
us_poll_init(accepted_p, client_fd, POLL_TYPE_SOCKET);
us_poll_start(accepted_p, listen_socket->s.context->loop, LIBUS_SOCKET_READABLE);
struct us_socket_t *s = (struct us_socket_t *) accepted_p;
s->context = listen_socket->s.context;
s->timeout = 0;
s->low_prio_state = 0;
/* We always use nodelay */
bsd_socket_nodelay(client_fd, 1);
us_internal_socket_context_link(listen_socket->s.context, s);
listen_socket->s.context->on_open(s, 0, bsd_addr_get_ip(addr), bsd_addr_get_ip_length(addr));
/* Exit accept loop if listen socket was closed in on_open handler */
return us_socket_is_closed(0, &listen_socket->s);
}
Looks fine can you make it a PR?
https://github.com/uNetworking/uSockets/pull/175
This is now possible and used in the uWS::LocalCluster you can look at HelloWorldThreaded