feat: implement new IPC layer

This commit is contained in:
2026-04-01 13:11:03 +02:00
parent 6276f8b162
commit 346977a0f9
34 changed files with 3210 additions and 897 deletions
+28
View File
@@ -76,6 +76,7 @@ namespace Montauk {
static constexpr uint64_t SYS_WINPOLL = 57;
static constexpr uint64_t SYS_WINENUM = 58;
static constexpr uint64_t SYS_WINMAP = 59;
static constexpr uint64_t SYS_WINUNMAP = 97;
static constexpr uint64_t SYS_WINSENDEVENT = 60;
static constexpr uint64_t SYS_WINRESIZE = 64;
static constexpr uint64_t SYS_WINSETSCALE = 65;
@@ -126,6 +127,28 @@ namespace Montauk {
static constexpr uint64_t SYS_FRENAME = 94;
static constexpr uint64_t SYS_GETCWD = 95;
static constexpr uint64_t SYS_CHDIR = 96;
static constexpr uint64_t SYS_DUPHANDLE = 98;
static constexpr uint64_t SYS_WAIT_HANDLE = 99;
static constexpr uint64_t SYS_STREAM_CREATE = 100;
static constexpr uint64_t SYS_STREAM_READ = 101;
static constexpr uint64_t SYS_STREAM_WRITE = 102;
static constexpr uint64_t SYS_MAILBOX_CREATE = 103;
static constexpr uint64_t SYS_MAILBOX_SEND = 104;
static constexpr uint64_t SYS_MAILBOX_RECV = 105;
static constexpr uint64_t SYS_WAITSET_CREATE = 106;
static constexpr uint64_t SYS_WAITSET_ADD = 107;
static constexpr uint64_t SYS_WAITSET_REMOVE = 108;
static constexpr uint64_t SYS_WAITSET_WAIT = 109;
static constexpr uint64_t SYS_PROC_OPEN = 110;
static constexpr uint64_t SYS_SURFACE_CREATE = 111;
static constexpr uint64_t SYS_SURFACE_MAP = 112;
static constexpr uint64_t SYS_SURFACE_RESIZE = 113;
static constexpr uint32_t IPC_SIGNAL_READABLE = 1u << 0;
static constexpr uint32_t IPC_SIGNAL_WRITABLE = 1u << 1;
static constexpr uint32_t IPC_SIGNAL_PEER_CLOSED = 1u << 2;
static constexpr uint32_t IPC_SIGNAL_EXITED = 1u << 3;
static constexpr uint32_t IPC_SIGNAL_READY = 1u << 4;
// Audio control commands (for SYS_AUDIOCTL)
static constexpr int AUDIO_CTL_SET_VOLUME = 0;
@@ -188,6 +211,11 @@ namespace Montauk {
uint8_t buttons;
};
struct IpcWaitResult {
int32_t index;
uint32_t signals;
};
// Window server shared types
struct WinEvent {
uint8_t type; // 0=key, 1=mouse, 2=resize, 3=close, 4=scale
+107
View File
@@ -79,6 +79,7 @@ extern "C" {
#define MTK_SYS_WINPOLL 57
#define MTK_SYS_WINENUM 58
#define MTK_SYS_WINMAP 59
#define MTK_SYS_WINUNMAP 97
#define MTK_SYS_WINSENDEVENT 60
#define MTK_SYS_PROCLIST 61
#define MTK_SYS_KILL 62
@@ -99,9 +100,30 @@ extern "C" {
#define MTK_SYS_GETTZ 91
#define MTK_SYS_GETCWD 95
#define MTK_SYS_CHDIR 96
#define MTK_SYS_DUPHANDLE 98
#define MTK_SYS_WAIT_HANDLE 99
#define MTK_SYS_STREAM_CREATE 100
#define MTK_SYS_STREAM_READ 101
#define MTK_SYS_STREAM_WRITE 102
#define MTK_SYS_MAILBOX_CREATE 103
#define MTK_SYS_MAILBOX_SEND 104
#define MTK_SYS_MAILBOX_RECV 105
#define MTK_SYS_WAITSET_CREATE 106
#define MTK_SYS_WAITSET_ADD 107
#define MTK_SYS_WAITSET_REMOVE 108
#define MTK_SYS_WAITSET_WAIT 109
#define MTK_SYS_PROC_OPEN 110
#define MTK_SYS_SURFACE_CREATE 111
#define MTK_SYS_SURFACE_MAP 112
#define MTK_SYS_SURFACE_RESIZE 113
#define MTK_SOCK_TCP 1
#define MTK_SOCK_UDP 2
#define MTK_IPC_SIGNAL_READABLE (1u << 0)
#define MTK_IPC_SIGNAL_WRITABLE (1u << 1)
#define MTK_IPC_SIGNAL_PEER_CLOSED (1u << 2)
#define MTK_IPC_SIGNAL_EXITED (1u << 3)
#define MTK_IPC_SIGNAL_READY (1u << 4)
/* Window event types */
#define MTK_EVENT_KEY 0
@@ -136,6 +158,11 @@ typedef struct {
uint8_t buttons;
} mtk_mouse_state;
typedef struct {
int32_t index;
uint32_t signals;
} mtk_ipc_wait_result;
typedef struct {
uint8_t type;
uint8_t _pad[3];
@@ -396,6 +423,78 @@ static inline int mtk_readdir(const char *path, const char **names, int max) {
return (int)_mtk_syscall3(MTK_SYS_READDIR, (long)path, (long)names, (long)max);
}
/* ====================================================================
Generic IPC
==================================================================== */
static inline int mtk_dup_handle(int handle) {
return (int)_mtk_syscall1(MTK_SYS_DUPHANDLE, (long)handle);
}
static inline uint32_t mtk_wait_handle(int handle, uint32_t wanted_signals, unsigned long timeout_ms) {
return (uint32_t)_mtk_syscall3(MTK_SYS_WAIT_HANDLE, (long)handle, (long)wanted_signals, (long)timeout_ms);
}
static inline int mtk_stream_create(int *out_read_handle, int *out_write_handle, unsigned long capacity) {
return (int)_mtk_syscall3(MTK_SYS_STREAM_CREATE, (long)out_read_handle, (long)out_write_handle, (long)capacity);
}
static inline int mtk_stream_read(int handle, void *buf, int max_len) {
return (int)_mtk_syscall3(MTK_SYS_STREAM_READ, (long)handle, (long)buf, (long)max_len);
}
static inline int mtk_stream_write(int handle, const void *data, int len) {
return (int)_mtk_syscall3(MTK_SYS_STREAM_WRITE, (long)handle, (long)data, (long)len);
}
static inline int mtk_mailbox_create(int *out_send_handle, int *out_recv_handle) {
return (int)_mtk_syscall2(MTK_SYS_MAILBOX_CREATE, (long)out_send_handle, (long)out_recv_handle);
}
static inline int mtk_mailbox_send(int handle, uint32_t msg_type, const void *data,
uint16_t len, int attach_handle) {
return (int)_mtk_syscall5(MTK_SYS_MAILBOX_SEND, (long)handle, (long)msg_type,
(long)data, (long)len, (long)attach_handle);
}
static inline int mtk_mailbox_recv(int handle, uint32_t *out_msg_type, void *data,
uint16_t *in_out_len, int *out_attach_handle) {
return (int)_mtk_syscall5(MTK_SYS_MAILBOX_RECV, (long)handle, (long)out_msg_type,
(long)data, (long)in_out_len, (long)out_attach_handle);
}
static inline int mtk_waitset_create(void) {
return (int)_mtk_syscall0(MTK_SYS_WAITSET_CREATE);
}
static inline int mtk_waitset_add(int waitset_handle, int target_handle, uint32_t signals) {
return (int)_mtk_syscall3(MTK_SYS_WAITSET_ADD, (long)waitset_handle, (long)target_handle, (long)signals);
}
static inline int mtk_waitset_remove(int waitset_handle, int index) {
return (int)_mtk_syscall2(MTK_SYS_WAITSET_REMOVE, (long)waitset_handle, (long)index);
}
static inline int mtk_waitset_wait(int waitset_handle, mtk_ipc_wait_result *out_ready, unsigned long timeout_ms) {
return (int)_mtk_syscall3(MTK_SYS_WAITSET_WAIT, (long)waitset_handle, (long)out_ready, (long)timeout_ms);
}
static inline int mtk_proc_open(int pid) {
return (int)_mtk_syscall1(MTK_SYS_PROC_OPEN, (long)pid);
}
static inline int mtk_surface_create(unsigned long byte_size) {
return (int)_mtk_syscall1(MTK_SYS_SURFACE_CREATE, (long)byte_size);
}
static inline void *mtk_surface_map(int handle) {
return (void *)_mtk_syscall1(MTK_SYS_SURFACE_MAP, (long)handle);
}
static inline int mtk_surface_resize(int handle, unsigned long new_size) {
return (int)_mtk_syscall2(MTK_SYS_SURFACE_RESIZE, (long)handle, (long)new_size);
}
/* ====================================================================
Memory
==================================================================== */
@@ -478,6 +577,10 @@ static inline int mtk_win_poll(int id, mtk_win_event *event) {
return (int)_mtk_syscall2(MTK_SYS_WINPOLL, (long)id, (long)event);
}
static inline int mtk_win_unmap(int id) {
return (int)_mtk_syscall1(MTK_SYS_WINUNMAP, (long)id);
}
static inline unsigned long mtk_win_resize(int id, int w, int h) {
return (unsigned long)_mtk_syscall3(MTK_SYS_WINRESIZE, (long)id, (long)w, (long)h);
}
@@ -486,6 +589,10 @@ static inline int mtk_win_enumerate(mtk_win_info *info, int max) {
return (int)_mtk_syscall2(MTK_SYS_WINENUM, (long)info, (long)max);
}
static inline unsigned long mtk_win_map(int id) {
return (unsigned long)_mtk_syscall1(MTK_SYS_WINMAP, (long)id);
}
static inline int mtk_win_setcursor(int id, int cursor) {
return (int)_mtk_syscall2(MTK_SYS_WINSETCURSOR, (long)id, (long)cursor);
}
+59
View File
@@ -223,6 +223,62 @@ namespace montauk {
(uint64_t)maxLen, (uint64_t)srcIp, (uint64_t)srcPort);
}
// Generic IPC
inline int dup_handle(int handle) {
return (int)syscall1(Montauk::SYS_DUPHANDLE, (uint64_t)handle);
}
inline uint32_t wait_handle(int handle, uint32_t wantedSignals, uint64_t timeoutMs = ~0ULL) {
return (uint32_t)syscall3(Montauk::SYS_WAIT_HANDLE, (uint64_t)handle,
(uint64_t)wantedSignals, timeoutMs);
}
inline int stream_create(int* outReadHandle, int* outWriteHandle, uint32_t capacity = 0) {
return (int)syscall3(Montauk::SYS_STREAM_CREATE, (uint64_t)outReadHandle,
(uint64_t)outWriteHandle, (uint64_t)capacity);
}
inline int stream_read(int handle, void* buf, int maxLen) {
return (int)syscall3(Montauk::SYS_STREAM_READ, (uint64_t)handle, (uint64_t)buf, (uint64_t)maxLen);
}
inline int stream_write(int handle, const void* data, int len) {
return (int)syscall3(Montauk::SYS_STREAM_WRITE, (uint64_t)handle, (uint64_t)data, (uint64_t)len);
}
inline int mailbox_create(int* outSendHandle, int* outRecvHandle) {
return (int)syscall2(Montauk::SYS_MAILBOX_CREATE, (uint64_t)outSendHandle, (uint64_t)outRecvHandle);
}
inline int mailbox_send(int handle, uint32_t msgType, const void* data, uint16_t len, int attachHandle = -1) {
return (int)syscall5(Montauk::SYS_MAILBOX_SEND, (uint64_t)handle, (uint64_t)msgType,
(uint64_t)data, (uint64_t)len, (uint64_t)(int64_t)attachHandle);
}
inline int mailbox_recv(int handle, uint32_t* outMsgType, void* data,
uint16_t* inOutLen, int* outAttachHandle = nullptr) {
return (int)syscall5(Montauk::SYS_MAILBOX_RECV, (uint64_t)handle, (uint64_t)outMsgType,
(uint64_t)data, (uint64_t)inOutLen, (uint64_t)outAttachHandle);
}
inline int waitset_create() {
return (int)syscall0(Montauk::SYS_WAITSET_CREATE);
}
inline int waitset_add(int waitsetHandle, int targetHandle, uint32_t signals) {
return (int)syscall3(Montauk::SYS_WAITSET_ADD, (uint64_t)waitsetHandle,
(uint64_t)targetHandle, (uint64_t)signals);
}
inline int waitset_remove(int waitsetHandle, int index) {
return (int)syscall2(Montauk::SYS_WAITSET_REMOVE, (uint64_t)waitsetHandle, (uint64_t)index);
}
inline int waitset_wait(int waitsetHandle, Montauk::IpcWaitResult* outReady, uint64_t timeoutMs = ~0ULL) {
return (int)syscall3(Montauk::SYS_WAITSET_WAIT, (uint64_t)waitsetHandle, (uint64_t)outReady, timeoutMs);
}
inline int proc_open(int pid) {
return (int)syscall1(Montauk::SYS_PROC_OPEN, (uint64_t)pid);
}
inline int surface_create(uint64_t byteSize) {
return (int)syscall1(Montauk::SYS_SURFACE_CREATE, byteSize);
}
inline void* surface_map(int handle) {
return (void*)syscall1(Montauk::SYS_SURFACE_MAP, (uint64_t)handle);
}
inline int surface_resize(int handle, uint64_t newSize) {
return (int)syscall2(Montauk::SYS_SURFACE_RESIZE, (uint64_t)handle, newSize);
}
// Process management
inline void waitpid(int pid) { syscall1(Montauk::SYS_WAITPID, (uint64_t)pid); }
@@ -435,6 +491,9 @@ namespace montauk {
inline uint64_t win_map(int id) {
return (uint64_t)syscall1(Montauk::SYS_WINMAP, (uint64_t)id);
}
inline int win_unmap(int id) {
return (int)syscall1(Montauk::SYS_WINUNMAP, (uint64_t)id);
}
inline int win_sendevent(int id, const Montauk::WinEvent* event) {
return (int)syscall2(Montauk::SYS_WINSENDEVENT, (uint64_t)id, (uint64_t)event);
}
+19 -5
View File
@@ -390,11 +390,14 @@ bool desktop_poll_external_windows(DesktopState* ds) {
for (int i = 0; i < ds->window_count; i++) {
if (ds->windows[i].external && ds->windows[i].ext_win_id == extId) {
found = true;
bool remapRequested = false;
uint64_t currentVa = (uint64_t)(uintptr_t)ds->windows[i].content;
if (ds->windows[i].content_w != extWins[e].width ||
ds->windows[i].content_h != extWins[e].height) {
ds->windows[i].content_w = extWins[e].width;
ds->windows[i].content_h = extWins[e].height;
ds->windows[i].dirty = true;
remapRequested = true;
if (ds->windows[i].state != WIN_MINIMIZED && ds->windows[i].state != WIN_CLOSED) {
changed = true;
}
@@ -411,12 +414,20 @@ bool desktop_poll_external_windows(DesktopState* ds) {
changed = true;
}
ds->windows[i].ext_cursor = extWins[e].cursor;
// Always verify mapping is current. If a window slot was
// recycled (app exited, new app got same slot), desktopVa
// was zeroed and Map() returns a new VA. Detect this and
// update the content pointer to avoid using a stale VA.
if (remapRequested && currentVa != 0) {
montauk::win_unmap(extId);
ds->windows[i].content = nullptr;
currentVa = 0;
}
uint64_t va = montauk::win_map(extId);
if (va != 0 && va != (uint64_t)(uintptr_t)ds->windows[i].content) {
if (!remapRequested && va != 0 && va != currentVa) {
montauk::win_unmap(extId);
va = montauk::win_map(extId);
}
if (va != 0 && va != currentVa) {
ds->windows[i].content = (uint32_t*)va;
ds->windows[i].content_w = extWins[e].width;
ds->windows[i].content_h = extWins[e].height;
@@ -508,6 +519,9 @@ bool desktop_poll_external_windows(DesktopState* ds) {
if (!stillExists) {
// Window gone — remove without freeing content (shared memory)
if (ds->windows[i].content != nullptr) {
montauk::win_unmap(extId);
}
ds->windows[i].content = nullptr; // prevent free
gui::desktop_close_window(ds, i);
changed = true;
+6 -2
View File
@@ -397,7 +397,9 @@ extern "C" void _start() {
}
}
}
montauk::yield();
uint64_t now = montauk::get_milliseconds();
if (now >= startMs + 10000) break;
montauk::wait_handle(fd, Montauk::IPC_SIGNAL_READABLE, startMs + 10000 - now);
}
if (!gotOffer) {
@@ -447,7 +449,9 @@ extern "C" void _start() {
}
}
}
montauk::yield();
uint64_t now = montauk::get_milliseconds();
if (now >= startMs + 10000) break;
montauk::wait_handle(fd, Montauk::IPC_SIGNAL_READABLE, startMs + 10000 - now);
}
montauk::closesocket(fd);
+8 -2
View File
@@ -198,8 +198,14 @@ static int plain_http_exchange(int fd, const char* request, int reqLen,
if (r > 0) { respLen += r; deadline = montauk::get_milliseconds() + 15000; }
else if (r < 0) break;
else {
if (montauk::get_milliseconds() >= deadline) break;
montauk::sleep_ms(1);
uint64_t now = montauk::get_milliseconds();
if (now >= deadline) break;
uint32_t signals = montauk::wait_handle(
fd,
Montauk::IPC_SIGNAL_READABLE | Montauk::IPC_SIGNAL_PEER_CLOSED,
deadline - now
);
if (signals == 0 || signals == (uint32_t)-1) break;
}
}
return respLen;
+11 -3
View File
@@ -386,9 +386,17 @@ static void handle_client(int clientFd) {
} else if (r == 0) {
break; // Connection closed
} else {
idleCount++;
if (idleCount > 500) break; // Timeout
montauk::yield();
uint32_t signals = montauk::wait_handle(
clientFd,
Montauk::IPC_SIGNAL_READABLE | Montauk::IPC_SIGNAL_PEER_CLOSED,
20
);
if (signals == 0) {
idleCount++;
if (idleCount > 500) break;
} else if (signals & Montauk::IPC_SIGNAL_PEER_CLOSED) {
break;
}
}
}
reqBuf[reqLen] = '\0';
+3 -1
View File
@@ -1028,7 +1028,9 @@ extern "C" void _start() {
}
} else {
if (!dirty) {
montauk::yield();
montauk::wait_handle(irc.fd,
Montauk::IPC_SIGNAL_READABLE | Montauk::IPC_SIGNAL_PEER_CLOSED,
10);
continue;
}
}
+1 -2
View File
@@ -187,8 +187,7 @@ extern "C" void _start() {
montauk::putchar(ev.ascii);
}
} else {
// No key and no data -- yield to avoid busy-spinning
montauk::yield();
montauk::wait_handle(fd, Montauk::IPC_SIGNAL_READABLE | Montauk::IPC_SIGNAL_PEER_CLOSED, 10);
}
}