Implement ipc_netsockdelete() syscall and automatic dangling socket cleanup

This commit is contained in:
2025-10-29 21:21:35 +01:00
parent 7db6a8e130
commit 4417141216
12 changed files with 107 additions and 7 deletions

View File

@ -9,6 +9,7 @@
#include "util/util.h"
#include "sysdefs/ipcnetsock.h"
#include "kprintf.h"
#include "proc/proc.h"
IpcNetSocks IPC_NETSOCKS;
@ -71,7 +72,7 @@ void ipc_netsock_event(uint16_t ev, struct pico_socket *sock1) {
spinlock_release(&netsock->spinlock);
}
IpcNetSock *ipc_netsockmake(uint16_t net, uint16_t proto, uint16_t port) {
IpcNetSock *ipc_netsockmake(uint16_t net, uint16_t proto, uint16_t port, uint64_t pid) {
IpcNetSock *netsock = dlmalloc(sizeof(*netsock));
if (netsock == NULL) {
return NULL;
@ -89,6 +90,8 @@ IpcNetSock *ipc_netsockmake(uint16_t net, uint16_t proto, uint16_t port) {
uint8_t *eventbuffer = dlmalloc(sizeof(IpcNetSockEventBuffer) * IPC_NETSOCK_EVENTBUFFER_MAX);
rbuft_init(&netsock->eventbuffer, eventbuffer, sizeof(IpcNetSockEventBuffer), IPC_NETSOCK_EVENTBUFFER_MAX);
netsock->ownerpid = pid;
uint16_t port_be = short_be(port);
struct pico_ip4 inaddr_any = {0};
pico_socket_bind(netsock->picosock, &inaddr_any, &port_be);
@ -110,3 +113,58 @@ int32_t ipc_netsocklisten(IpcNetSock *netsock, size_t maxlisteners) {
spinlock_release(&netsock->spinlock);
return r == 0 ? E_OK : E_NETSOCKLISTEN;
}
int32_t ipc_netsockdelete_nolock(IpcNetSock *netsock) {
LL_REMOVE(IPC_NETSOCKS.netsocks, netsock);
spinlock_acquire(&netsock->spinlock);
pico_socket_del(netsock->picosock);
ipc_pipefree(netsock->datapipe);
dlfree(netsock->datapipe);
dlfree(netsock->eventbuffer.buffer);
spinlock_release(&netsock->spinlock);
dlfree(netsock);
return E_OK;
}
int32_t ipc_netsockdelete(IpcNetSock *netsock) {
spinlock_acquire(&IPC_NETSOCKS.spinlock);
LL_REMOVE(IPC_NETSOCKS.netsocks, netsock);
spinlock_release(&IPC_NETSOCKS.spinlock);
spinlock_acquire(&netsock->spinlock);
pico_socket_del(netsock->picosock);
ipc_pipefree(netsock->datapipe);
dlfree(netsock->datapipe);
dlfree(netsock->eventbuffer.buffer);
spinlock_release(&netsock->spinlock);
dlfree(netsock);
return E_OK;
}
void ipc_netsock_cleanup_dangling(void) {
IpcNetSock *ns, *nstmp;
spinlock_acquire(&IPC_NETSOCKS.spinlock);
spinlock_acquire(&PROCS.spinlock);
LL_FOREACH_SAFE(IPC_NETSOCKS.netsocks, ns, nstmp) {
bool foundowner = false;
Proc *proc, *proctmp;
LL_FOREACH_SAFE(PROCS.procs, proc, proctmp) {
if (ns->ownerpid == proc->pid) {
foundowner = true;
break;
}
}
if (!foundowner) {
ipc_netsockdelete_nolock(ns);
}
}
spinlock_release(&PROCS.spinlock);
spinlock_release(&IPC_NETSOCKS.spinlock);
}

View File

@ -16,6 +16,7 @@ typedef struct IpcNetSock {
IpcPipe *datapipe;
RBufT eventbuffer;
SpinLock spinlock;
uint64_t ownerpid;
} IpcNetSock;
typedef struct {
@ -26,7 +27,9 @@ typedef struct {
extern IpcNetSocks IPC_NETSOCKS;
void ipc_netsockinit(void);
IpcNetSock *ipc_netsockmake(uint16_t net, uint16_t proto, uint16_t port);
IpcNetSock *ipc_netsockmake(uint16_t net, uint16_t proto, uint16_t port, uint64_t pid);
int32_t ipc_netsocklisten(IpcNetSock *netsock, size_t maxlisteners);
int32_t ipc_netsockdelete(IpcNetSock *netsock);
void ipc_netsock_cleanup_dangling(void);
#endif // NETSOCK_NETSOCK_H_

View File

@ -13,6 +13,7 @@
#include "vfs/vfs.h"
#include "bootinfo/bootinfo.h"
#include "ipc/pipe/pipe.h"
#include "ipc/netsock/netsock.h"
#include "sysdefs/proc.h"
#include "sysdefs/fs.h"
#include "time/time.h"
@ -246,6 +247,7 @@ void proc_reaper(void) {
void proc_sched(void *cpustate) {
hal_intr_disable();
sched_ticks++;
ipc_netsock_cleanup_dangling();
update_time();
pico_stack_tick();

View File

@ -11,7 +11,7 @@ int32_t SYSCALL3(sys_ipc_netsockmake, net1, proto1, port1) {
uint16_t proto = proto1;
uint16_t port = port1;
IpcNetSock *netsock = ipc_netsockmake(net, proto, port);
IpcNetSock *netsock = ipc_netsockmake(net, proto, port, _caller_pid);
if (netsock == NULL) {
return E_NOMEMORY;
@ -82,3 +82,23 @@ int32_t SYSCALL1(sys_ipc_netsockpollev, socknum1) {
return (int32_t)ev;
}
int32_t SYSCALL1(sys_ipc_netsockdelete, socknum1) {
size_t socknum = socknum1;
spinlock_acquire(&IPC_NETSOCKS.spinlock);
size_t idx = 0;
IpcNetSock *ns, *nstmp;
LL_FOREACH_SAFE_IDX(IPC_NETSOCKS.netsocks, ns, nstmp, idx) {
if (idx == socknum) {
break;
}
}
spinlock_release(&IPC_NETSOCKS.spinlock);
if (ns == NULL) {
return E_NOENTRY;
}
return ipc_netsockdelete(ns);
}

View File

@ -8,5 +8,6 @@
int32_t SYSCALL3(sys_ipc_netsockmake, net1, proto1, port1);
int32_t SYSCALL2(sys_ipc_netsocklisten, socknum1, maxlisteners1);
int32_t SYSCALL1(sys_ipc_netsockpollev, socknum1);
int32_t SYSCALL1(sys_ipc_netsockdelete, socknum1);
#endif // SYSCALL_IPC_NETSOCK_H_

View File

@ -68,4 +68,5 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = {
[SYS_IPC_NETSOCKMAKE] = &sys_ipc_netsockmake,
[SYS_IPC_NETSOCKLISTEN] = &sys_ipc_netsocklisten,
[SYS_IPC_NETSOCKPOLLEV] = &sys_ipc_netsockpollev,
[SYS_IPC_NETSOCKDELETE] = &sys_ipc_netsockdelete,
};

View File

@ -38,5 +38,6 @@
#define SYS_IPC_NETSOCKMAKE 39
#define SYS_IPC_NETSOCKLISTEN 40
#define SYS_IPC_NETSOCKPOLLEV 41
#define SYS_IPC_NETSOCKDELETE 42
#endif // SHARE_HDRS_SYSCALL_H_

View File

@ -154,3 +154,7 @@ int32_t ipc_netsocklisten(uint64_t netsock, size_t maxlisteners) {
int32_t ipc_netsockpollev(uint64_t netsock) {
return syscall(SYS_IPC_NETSOCKPOLLEV, (uint64_t)netsock, 0, 0, 0, 0, 0);
}
int32_t ipc_netsockdelete(uint64_t netsock) {
return syscall(SYS_IPC_NETSOCKDELETE, (uint64_t)netsock, 0, 0, 0, 0, 0);
}

View File

@ -47,5 +47,6 @@ int32_t time(Time *time);
int32_t ipc_netsockmake(uint16_t net, uint16_t proto, uint16_t port);
int32_t ipc_netsocklisten(uint64_t netsock, size_t maxlisteners);
int32_t ipc_netsockpollev(uint64_t netsock);
int32_t ipc_netsockdelete(uint64_t netsock);
#endif // ULIB_SYSTEM_SYSTEM_H_

View File

@ -12,8 +12,10 @@ void main(void) {
if (string_strcmp(cmd, "block") == 0) {
diagdummy_block();
} else if (string_strcmp(cmd, "tcp-test") == 0) {
diagdummy_tcptest();
} else if (string_strcmp(cmd, "tcp-test-server") == 0) {
diagdummy_tcptestserver();
} else if (string_strcmp(cmd, "tcp-test-client") == 0) {
diagdummy_tcptestclient();
} else {
uprintf("diagdummy: unknown cmd %s\n", cmd);
}

View File

@ -4,7 +4,7 @@
#define MAX_CONNS 10
void diagdummy_tcptest(void) {
void diagdummy_tcptestserver(void) {
netsock_t netsock = ipc_netsockmake(NETSOCK_IPV4, NETSOCK_TCP, 1);
ipc_netsocklisten(netsock, MAX_CONNS);
@ -16,4 +16,10 @@ void diagdummy_tcptest(void) {
} else {
}
}
ipc_netsockdelete(netsock);
}
void diagdummy_tcptestclient(void) {
}

View File

@ -1,6 +1,7 @@
#ifndef DIAGDUMMY_TCPTEST_H_
#define DIAGDUMMY_TCPTEST_H_
void diagdummy_tcptest(void);
void diagdummy_tcptestserver(void);
void diagdummy_tcptestclient(void);
#endif // DIAGDUMMY_TCPTEST_H_