feat: implement new IPC layer
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user