mirror of
https://github.com/HeyPuter/gex.git
synced 2026-11-13 20:12:43 -10:00
Wine's wineserver makes every socket and hands its client the descriptor, often before either has used it: the client sets an option, then the server binds, listens or connects it and polls it while the client sends and receives on it. In a page each process has its own memory, and carry_name could only carry a connected TCP socket, so a UDP or unconnected TCP socket was left behind in transit: wine_server_receive_fd got nothing and every option call failed with STATUS_TOO_MANY_OPENED_FILES (Warfork W64's "Couldn't open UDP socket: setsockopt: Unknown error"). Such a socket now moves to the global kernel the first time it leaves its process (net::Socket::move_out, "inetg:KIND:ID"): its state goes there (k_inet_adopt) and each process's descriptor is a hold on it that forwards every call (k_inet_op, one net::op per Socket method), with the socket's own locks and a table lock held only to find it. A socket that never leaves its process is unchanged but for one load per call. A moved TCP socket's connection out is a Wisp stream the connecting process opens (go_out); the global kernel keeps its name and each other holder takes it up at its next call (come_back). Tests: crates/gex-kernel/tests/inet_move.rs; tests/wasm32/sockpass-page.sh gains the unconnected cases (UDP passed unbound, a close in either process while the other polls, TCP listen and connect on a passed socket, and a remote connect out), which fail on master and pass in MP and SP. Warfork W64 in the page now reaches its main menu. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_40f26e8988a74ea098d8bc80ff68287c