remove host thread

This commit is contained in:
jacob 2025-07-14 16:42:44 -05:00
parent 0a20e3fdd4
commit f27ec95481
4 changed files with 192 additions and 294 deletions

View File

@ -156,7 +156,6 @@ GLOBAL struct {
i32 _;
} G = ZI, DEBUG_ALIAS(G, G_host);
INTERNAL SYS_THREAD_DEF(host_receiver_thread_entry_point, arg);
INTERNAL void host_msg_assembler_release(struct host_msg_assembler *ma);
/* ========================== *
@ -198,19 +197,11 @@ struct host *host_alloc(u16 listen_port)
host->sock = sock_alloc(listen_port, MEBI(2), MEBI(2));
host->receiver_thread = sys_thread_alloc(&host_receiver_thread_entry_point, host, LIT("Host receiver"), PROF_THREAD_GROUP_IO);
return host;
}
void host_release(struct host *host)
{
atomic32_fetch_set(&host->receiver_thread_shutdown_flag.v, 1);
sock_wake(host->sock);
while (!sys_thread_try_release(host->receiver_thread, 0.001f)) {
sock_wake(host->sock);
}
sock_release(host->sock);
buddy_ctx_release(host->buddy);
@ -648,25 +639,41 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
struct host_event_list events = ZI;
i64 now_ns = sys_time_ns();
{
__profn("Read host packets");
struct string read_buff = ZI;
read_buff.len = PACKET_DATA_MAX_LEN;
read_buff.text = arena_push_array_no_zero(scratch.arena, u8, read_buff.len);
__profn("Read packets");
/* Swap read & write rcv buffers */
/* Read socket */
struct host_rcv_packet *first_packet = 0;
struct host_rcv_packet *last_packet = 0;
{
struct snc_lock lock = snc_lock_e(&host->rcv_buffer_write_mutex);
struct host_rcv_buffer *swp = host->rcv_buffer_read;
host->rcv_buffer_read = host->rcv_buffer_write;
host->rcv_buffer_write = swp;
snc_unlock(&lock);
__profn("Read socket");
struct sock_array socks = ZI;
socks.socks = &host->sock;
socks.count = 1;
struct sock *sock = host->sock;
struct sock_read_result res = ZI;
while ((res = sock_read(scratch.arena, sock)).valid) {
struct sock_address address = res.address;
struct string data = res.data;
if (data.len > 0) {
struct host_rcv_packet *packet = arena_push(scratch.arena, struct host_rcv_packet);
packet->address = address;
packet->data = string_copy(scratch.arena, data);
if (last_packet) {
last_packet->next = packet;
} else {
first_packet = packet;
}
last_packet = packet;
}
}
}
/* Read incoming packets */
struct host_rcv_buffer *rcv_buffer = host->rcv_buffer_read;
for (struct host_rcv_packet *packet = rcv_buffer->first_packet; packet; packet = packet->next) {
{
__profn("Process host packets");
for (struct host_rcv_packet *packet = first_packet; packet; packet = packet->next) {
//struct sock *sock = packet->sock;
struct sock_address address = packet->address;
struct bitbuff bb = bitbuff_from_string(packet->data);
@ -818,10 +825,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host)
host->bytes_received += packet->data.len;
}
}
/* Reset read buffer */
rcv_buffer->first_packet = 0;
rcv_buffer->last_packet = 0;
arena_reset(rcv_buffer->arena);
}
}
/* Update channels */
@ -1053,50 +1057,3 @@ void host_update_end(struct host *host)
scratch_end(scratch);
}
/* ========================== *
* Receive thread
* ========================== */
INTERNAL SYS_THREAD_DEF(host_receiver_thread_entry_point, arg)
{
u64 read_buff_size = KIBI(64);
struct arena *read_buff_arena = arena_alloc(read_buff_size);
struct string read_buff = ZI;
read_buff.len = read_buff_size;
read_buff.text = arena_push_array_no_zero(read_buff_arena, u8, read_buff_size);
struct host *host = (struct host *)arg;
struct sock_array socks = ZI;
socks.socks = &host->sock;
socks.count = 1;
struct atomic32 *shutdown = &host->receiver_thread_shutdown_flag.v;
while (!atomic32_fetch(shutdown)) {
struct sock *sock = sock_wait_for_available_read(socks, F32_INFINITY);
struct sock_read_result res;
while (!atomic32_fetch(shutdown) && sock && (res = sock_read(sock, read_buff)).valid) {
struct sock_address address = res.address;
struct string data = res.data;
if (data.len > 0) {
struct snc_lock lock = snc_lock_e(&host->rcv_buffer_write_mutex);
{
struct host_rcv_buffer *rcv_buffer = host->rcv_buffer_write;
struct host_rcv_packet *packet = arena_push(rcv_buffer->arena, struct host_rcv_packet);
packet->address = address;
packet->data = string_copy(rcv_buffer->arena, data);
if (rcv_buffer->last_packet) {
rcv_buffer->last_packet->next = packet;
} else {
rcv_buffer->first_packet = packet;
}
rcv_buffer->last_packet = packet;
}
snc_unlock(&lock);
}
}
}
arena_release(read_buff_arena);
}

View File

@ -97,9 +97,6 @@ struct host {
u64 bytes_received;
u64 bytes_sent;
struct atomic32_padded receiver_thread_shutdown_flag;
struct sys_thread *receiver_thread;
};
/* ========================== *

View File

@ -43,11 +43,7 @@ INLINE b32 sock_address_eq(struct sock_address a, struct sock_address b)
struct sock *sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size);
void sock_release(struct sock *sock);
/* Wake anyone blocking on sock read */
void sock_wake(struct sock *sock);
struct sock *sock_wait_for_available_read(struct sock_array socks, f32 timeout);
struct sock_read_result sock_read(struct sock *sock, struct string read_buff);
struct sock_read_result sock_read(struct arena *arena, struct sock *sock);
void sock_write(struct sock *sock, struct sock_address address, struct string data);
#endif

View File

@ -14,10 +14,6 @@
#pragma comment(lib, "ws2_32.lib")
//#define MAX_IP_STR_LEN 46
#define MAX_POLL_FDS 64
struct win32_address {
i32 size;
i32 family;
@ -240,6 +236,7 @@ INTERNAL struct win32_address win32_address_from_sock_address(struct sock_addres
return res;
}
#if 0
/* If supplied address has ip INADDR_ANY (0), convert ip to localhost */
INTERNAL struct win32_address win32_address_convert_any_to_localhost(struct win32_address addr)
{
@ -271,6 +268,7 @@ INTERNAL struct win32_address win32_address_convert_any_to_localhost(struct win3
}
return addr;
}
#endif
INTERNAL struct sock_address sock_address_from_win32_address(struct win32_address ws_addr)
{
@ -293,7 +291,7 @@ INTERNAL struct sock_address sock_address_from_win32_address(struct win32_addres
* Sock
* ========================== */
INTERNAL struct win32_sock *win32_sock_alloc(void)
struct sock *sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size)
{
struct win32_sock *ws = 0;
{
@ -307,24 +305,9 @@ INTERNAL struct win32_sock *win32_sock_alloc(void)
snc_unlock(&lock);
}
MEMZERO_STRUCT(ws);
return ws;
}
INTERNAL void win32_sock_release(struct win32_sock *ws)
{
struct snc_lock lock = snc_lock_e(&G.win32_socks_mutex);
ws->next_free = G.first_free_win32_sock;
G.first_free_win32_sock = ws;
snc_unlock(&lock);
}
struct sock *sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size)
{
struct win32_sock *ws = win32_sock_alloc();
struct sock_address addr = sock_address_from_port(listen_port);
struct win32_address bind_address = win32_address_from_sock_address(addr);
ws->sock = socket(bind_address.family, SOCK_DGRAM, IPPROTO_UDP);
{
i32 sb = sndbuf_size;
i32 rb = rcvbuf_size;
@ -333,6 +316,8 @@ struct sock *sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size)
}
bind(ws->sock, &bind_address.sa, bind_address.size);
u32 imode = 1;
ioctlsocket(ws->sock, FIONBIO, (unsigned long *)&imode);
return (struct sock *)ws;
}
@ -341,67 +326,27 @@ void sock_release(struct sock *sock)
{
struct win32_sock *ws = (struct win32_sock *)sock;
closesocket(ws->sock);
win32_sock_release(ws);
}
/* Send an empty dummy packet to wake anyone blocking on read.
* This is hack since winsock doesn't have eventfd.
*
* TODO: Use WSAEvent and WSAWaitForMultipleEvents instead */
void sock_wake(struct sock *sock)
{
struct win32_sock *ws = (struct win32_sock *)sock;
/* Get bound address as localhost so we can write to it (if bound to INADDR_ANY) */
struct win32_address bind_address = ZI;
struct snc_lock lock = snc_lock_e(&G.win32_socks_mutex);
{
i32 len = sizeof(bind_address.sas);
getsockname(ws->sock, &bind_address.sa, &len);
bind_address.family = bind_address.sin.sin_family;
bind_address.size = len;
bind_address = win32_address_convert_any_to_localhost(bind_address);
ws->next_free = G.first_free_win32_sock;
G.first_free_win32_sock = ws;
}
/* Have sock send an empty dummy packet to itself to signal read available */
sendto(ws->sock, "", 0, 0, &bind_address.sa, bind_address.size);
snc_unlock(&lock);
}
/* ========================== *
* Read
* ========================== */
struct sock *sock_wait_for_available_read(struct sock_array socks, f32 timeout)
{
struct sock *res = 0;
WSAPOLLFD fds[MAX_POLL_FDS] = ZI;
for (u32 i = 0; i < socks.count; ++i) {
struct win32_sock *ws = (struct win32_sock *)socks.socks[i];
fds[i].fd = ws->sock;
fds[i].events = POLLRDNORM;
}
i32 timeout_ms;
if (timeout == F32_INFINITY) {
timeout_ms = -1;
} else {
timeout_ms = (i32)(timeout * 1000);
}
WSAPoll(fds, socks.count, timeout_ms);
for (u64 i = 0; i < socks.count; ++i) {
if (fds[i].revents & POLLRDNORM) {
res = socks.socks[i];
break;
}
}
return res;
}
struct sock_read_result sock_read(struct sock *sock, struct string read_buff)
struct sock_read_result sock_read(struct arena *arena, struct sock *sock)
{
struct win32_sock *ws = (struct win32_sock *)sock;
u64 read_buff_size = KIBI(64);
struct string read_buff = ZI;
read_buff.len = read_buff_size;
read_buff.text = arena_push_array_no_zero(arena, u8, read_buff_size);
struct sock_read_result res = ZI;
struct win32_address ws_addr = ZI;
@ -416,6 +361,9 @@ struct sock_read_result sock_read(struct sock *sock, struct string read_buff)
res.data.text = read_buff.text;
res.data.len = size;
res.valid = 1;
/* Pop arena back to end of msg */
arena_pop_to(arena, arena->pos - read_buff_size + size);
} else {
#if RTC
i32 err = WSAGetLastError();