Add DevListenServer TCP listener with hello/ping handshake#95
Merged
Conversation
mblackman
added a commit
that referenced
this pull request
May 31, 2026
POSIX recv/send return ssize_t and take size_t; Winsock returns int and takes int. -Werror=conversion on the linux/macos legs flagged the implicit ssize_t -> int narrowing in the engine source and would flag the test too. Introduce io_size_t / io_ssize_t typedefs picked per-platform so the same call shape compiles cleanly under both. Fixes the linux (editor-release) and macos (editor-release) CI failures on PR #95.
Stage 6 PR-A of ai/EditorBuildAndDeployPlan.md — foundation for the
dev-iterate loop. TCP listener the editor (and other tooling) dials into;
ships the socket + thread infrastructure plus the hello + ping ops. PR-B
will land eval_lua / reload_scene / push_script / push_asset.
- New src/Dev/DevListenServer.{h,cpp}; bound to 127.0.0.1:<port>
(--dev-listen) or 0.0.0.0 (--dev-listen-all). Compile-stripped from
shipped builds via OCTARINE_SHIPPED on header / .cpp / CMake / Game / Main.
- Wired into the per-layer engine split: Dev/DevListenServer.cpp joins
octarine_engine (non-shipped only) and ws2_32 is linked there on Windows.
- Listener uses a non-blocking accept gated by select() with a 100ms
timeout; Stop() flips a stop flag, joins, then closes the socket. Closing
the listen fd does NOT wake a blocked accept() on Linux, so the prior
close-before-join hung the join() forever (6h CI timeout on the
editor-release leg); the select loop has no blocking accept to wake.
Accepted client sockets are forced back to blocking so ReadAll/WriteAll
keep their >0 / <=0 semantics (Windows-accepted sockets inherit the
listener's non-blocking flag).
Verified: editor-debug + editor-release (-Werror) build clean; ctest
DevListenServerTest green, 25/25 release runs with no hang.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stage 6 PR-A of
ai/EditorBuildAndDeployPlan.md— foundation for the dev-iterate loop. TCP listener the editor (and other tooling) will dial into for asset / script push and Lua eval. This PR ships the socket + thread infrastructure and thehello+pingops; PR-B will landeval_lua/reload_scene/push_script/push_asset.src/Dev/DevListenServer.{h,cpp}— Registry singleton, listener thread bound to127.0.0.1:<port>(or0.0.0.0with--dev-listen-all). Compile-stripped from ship builds via#ifndef OCTARINE_SHIPPEDon header / .cpp / CMake / Game / Main.u32 length | u32 op | body[length-4].10 EvalLua,11 ReloadScene,12 PushScript,13 PushAsset) noted in code so we don't reuse them.ws2_32linked,WSAStartuprefcounted so tests + engine share one init).--dev-listen <port>opts in;--dev-listen-allflips the bind to0.0.0.0with a loudLogger::Warn. Both flags log a "stripped by shipped build" warning when seen in a shipped binary and parse no-op so they cannot eat a CLI slot.Pump()runs on the main thread per frame; PR-A has nothing to drain through it. PR-B will SPSC the not-thread-safe ops (Lua eval, scene reload, asset writes) through it.Out of scope (PR-B + later):
eval_lua/reload_scene/push_script/push_asset)nlohmann-jsonif metadata needs it)Test plan
cmake --preset editor-debug -DOCTARINE_ENABLE_TESTS=ON && cmake --build build/editor-debug --target OctarineDevListenServerTest— clean compile on Windows. ws2_32 links.ctest -R DevListenServerTest— green locally (0.01s). Asserts: Start on ephemeral port, Hello banner roundtrip, Ping echoes nonce, Stop joins thread cleanly, Stop+Start cycle clean.ws2_32(CMake guard) and does not compile the .cpp (SRC_FILES guard).--dev-listen 9001, dial in withpython -c "import socket,struct; s=socket.create_connection(('127.0.0.1',9001)); s.send(struct.pack('<II',4,1)); print(s.recv(256))", observe banner.