feat(el-runtime): native Windows port of el_runtime.c (+ engram_node_full corruption fix) #55
Reference in New Issue
Block a user
Delete Branch "feat/windows-el-runtime"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Native Windows port of el_runtime.c plus the engram_node_full corruption fixes the port was based on (2026-06-15).
Commits (not yet in main):
The first two are engram data-integrity fixes; the last two are the Windows runtime port. Opening for Will to review.
🤖 Generated with Claude Code
http_handler_fn / http_handler4_fn were defined only inside el_runtime.c, so soul modules (routes/chat/...) that reference them via cross-module forward declarations couldn't see the types — which broke the Windows link of every module. Moving the public function-pointer types to the shared header is the correct home and unblocks the build on all platforms (identical typedef, C11-safe redefinition in el_runtime.c). With this, the soul links into a native Windows neuron.exe (mingw, static) that boots and serves HTTP on :7770 — verified /health → 200 {"status":"alive",...} in a Win11 VM. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Review:
feat(el-runtime): native Windows port of el_runtime.c (+ engram)Thanks for the port Tim — the overall structure is solid (consistent
_WIN32guards, correct Winsock include ordering,WSAStartupvia__attribute__((constructor)), winpthreads strategy). That said there are 5 blockers across two categories that need to land before this can merge.Blockers — will not compile or link
1.
nanosleephas no Windows shimnanosleep()is called in four places inel_runtime.cwith no shim inel_platform_win.h. On mingw-w64 this is a linker error. Needs aSleep()-based replacement (e.g.timeBeginPeriod(1)+Sleep(ms)for sub-millisecond precision, or justSleep(ns/1e6)).2. Duplicate
http_handler_fn/http_handler4_fntypedefsThese typedefs are now defined in both
el_runtime.h(newly promoted) and as localtypedefs insideel_runtime.c. C11 doesn't allow duplicate typedef declarations of the same type — this is a compile error under-Wpedantic/-Werroron all platforms, not just Windows.3.
el_mem_checkdeclared but definition deletedThe function body was removed in this PR but the declaration remains in
el_runtime.h. Any caller gets an undefined symbol at link time on both Windows and Unix.Blockers — runtime correctness on Windows
4.
close(fd)inhttp_worker/http_worker_v2(line ~1576, ~1826)http_workerandhttp_worker_v2callclose(fd)in their teardown paths. On Windows,close()is the CRT file-descriptor closer — it does nothing to Winsock sockets. Every HTTP request leaks oneSOCKEThandle. Theaccept()-loop error paths were correctly migrated toel_closesocket()but the normal teardown paths were not. A long-running server exhausts system handle space and starts rejecting connections.5.
accept()→int cfdtruncates 64-bitSOCKEThandle (line ~1613, ~1863)accept()returnsSOCKET(UINT_PTR, 64-bit unsigned). Storing that inint cfdsilently truncates the upper 32 bits.HttpWorkerArg.fdis alsotypedef'd asint(line ~1539), so the corrupted handle is passed through to the worker thread. Any socket handle above0x7FFFFFFFcausesWSAENOTSOCKor closes the wrong descriptor. GCC-Wconversionfires on mingw-w64 for this narrowing. Fix:HttpWorkerArg.fdshould beSOCKET(oruintptr_t) behind#ifdef _WIN32.Significant — fix before merge
6.
unsetenv("TZ")shim setsTZ=""instead of removing it_el_apply_zone()callsunsetenv("TZ") + tzset()to restore the OS local timezone. POSIX: TZ removed → tzset reads/etc/localtime→ correct local time. Your shim calls_putenv_s("TZ", "")which sets TZ to an empty string, not removes it —_tzset()seesTZ=""and silently falls back to UTC. All El programs doing local-timezone date operations on Windows return UTC. Fix: use_putenv_s("TZ=", "")(the environment deletion form) or checkSetEnvironmentVariable("TZ", NULL).7. IANA timezone names silently broken on Windows CRT
_el_apply_zone()passes IANA names (e.g.America/New_York) tosetenv("TZ"). The Windows CRT only understands POSIX timezone specs (e.g.EST5EDT,M3.2.0,M11.1.0). On Windows, IANA names produce no error — the CRT just defaults to UTC. Either require callers to pass POSIX specs, or bundle a minimal IANA→POSIX lookup table.8.
el_closesocket(int s)parameter typeSOCKETisUINT_PTR(64-bit). Theintparameter means handles above0x7FFFFFFFare sign-extended before being passed toclosesocket(). Same root issue as finding #5. Parameter should beSOCKEToruintptr_tbehind#ifdef _WIN32.9.
EINTRretry afteraccept()never fires on WindowsThe
accept()error path checkserrno == EINTR. On Windows, Winsock errors come fromWSAGetLastError(), noterrno. Any transient socket error permanently exits the server loop instead of retrying.Minor
setenvshim ignoresoverwrite=0— no current callers use it but the contract is violatedWSAStartupreturn not checked;initedset to 1 even on failure (silently breaks all networking with no diagnostic)x86_64-w64-mingw32-gccbuild succeedsWhat's working
Platform detection is clean and consistent, WSAStartup/include ordering is correct, threading via winpthreads needs no changes,
exec_bg/CreateProcesspath is properly guarded,setsockoptcast toconst char*is correct.Do not merge until the 5 blockers above are resolved.