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);
}