Skip to content

fix: restore main-only v3.9 fixes that never reached dev - #350

Merged
gg582 merged 4 commits into
devfrom
fix/restore-main-only-fixes
Oct 10, 2026
Merged

gg582 merged 4 commits into
devfrom
fix/restore-main-only-fixes

Conversation

@gg582

@gg582 gg582 commented Oct 10, 2026

Copy link
Copy Markdown
Member

Brings back to dev the main-only work that v3.9 shipped but that never reached dev.

How this was found: I compared v3.9 against current dev file by file. For every line that exists only in v3.9, I checked whether dev had deliberately replaced it.

  • Most such lines are older code that dev has since superseded: the old static task ring, the old async claim spin, the old gc.h docs, the HTTP/3 changes. Those are left alone.
  • What remained is listed below. Each item was added on main only, mostly in Jiho Lee's 2026-09-14 batch, and before the histories were joined it was never ported to dev.

Commits

  1. fix(api): restore the inert CWIST_ENDPOINT_PUBLIC_FIXED bit (79144d1)

  2. fix: complete shutdown writes and transfer queue ownership (7dfe8be, author Jiho Lee, port of 3122858)

    • kqueue.c: the BSD io_queue now disowns the queue and each submitted job from the allocating thread's full-GC sweep, as the other backend already does. A submit whose job allocation failed now returns an error instead of dereferencing NULL.
    • http.c: during shutdown, a coalesced batch is sent with a blocking write, instead of being parked on a reactor callback that will never run.
    • tests/test_gc_job_handoff.c is wired into TEST_TARGETS, running the gc, nogc and runtime modes, plus gc and nogc again under -DNDEBUG.
    • The io_queue.c and scheduler.c halves are already on dev from dcb561b.
  3. fix(http): isolate blocking pipelined request bodies (dfb75b9, author Jiho Lee, port of c5f289e)

    • cwist_http_receive_request() passed everything read so far to the header parser. When a pipelined request was already in the buffer, its bytes were taken as the current request's body.
    • This is a real bug on dev. The restored check_blocking_pipeline cases fail on dev without the fix (body-size assertion) and pass with it.
  4. docs(app): cwist_app_listen() defaults to one worker per core again (bd9ec85)

Deliberately not restored

  • The bdr_ctx field comment "Legacy standalone BDR storage; never replayed by HTTP dispatch". Dispatch does replay it, through the perf(bdr): per-connection cursor fast path for cached GET replies #194 pinned-cursor path, on both branches, so dev's comment is the accurate one.
  • Unused or deleted files: tests/support/cjson/cJSON.h (nothing includes it), tests/bench_gc_alloc_overhead.c (never wired), docs/roadmap-v3.5.md (not referenced), scripts/ci/rust_hello_smoke.sh (deleted on dev in 45f9f7a), and the legacy othello-web Go files (also deleted on main).

Verification

Under ASan + UBSan, these pass: test_gc_job_handoff, test_http_pipeline, test_shutdown, test_https, test_https_park, test_https_park_full_gc, test_http2, test_conn_registry, test_full_gc_sweep, test_io_queue_full_gc, test_metrics, test_websocket. check_test_wiring.py and cwist audit --gate are clean. kqueue.c only builds on BSD, so the kqueue CI job covers it.

gg582 and others added 4 commits October 11, 2026 00:56
v3.9 ships CWIST_ENDPOINT_PUBLIC_FIXED (1u << 3) in endpoint_opts.h.
When #194 replaced the public FIXED cache, cf69362 removed the cache
but kept this bit defined (inert) "on both branches" so code that sets
it keeps compiling; dev never actually received the definition, so a
program built against v3.9 that passes it fails to compile on dev and
the v4.0 API baseline was recorded without it.

Take v3.9's endpoint_opts.h, which also replaces dev's stale "proposed
opt-in, draft PR #85" wording with the current description.
…122858)

Port the parts of main's 3122858 that never reached dev (dev already
has the io_queue.c and scheduler.c disowns, from dcb561b):

- kqueue.c: the BSD io_queue disowns the queue and each submitted job
  from the allocating thread's full-GC sweep list, as the io_uring/epoll
  backend does, and fails a submit whose job allocation failed instead
  of dereferencing NULL.
- http.c: during shutdown the reactor loop no longer runs, so a
  coalesced batch is finished with a blocking send instead of being
  parked on a callback that will never fire.
- tests/test_gc_job_handoff.c, wired into TEST_TARGETS. The recipe runs
  the gc, nogc and runtime modes, then gc and nogc again under -DNDEBUG
  (main's two recipes for this target, combined).
main's c5f289e never reached dev. cwist_http_receive_request() passed
everything read so far to the header parser, so with a pipelined
request already in the buffer the next request's bytes were taken as
this request's body. Parse only the header block, as the nonblocking
receiver does, and leave body framing to the code below.

The check_blocking_pipeline cases in tests/test_http_pipeline.c fail
on dev without this change (body size assertion) and pass with it.
f1e242e (#335) reverted the worker default to one process per online
core, but the cwist_app_listen() comment still described #333's "one per
three cores, at least 2". Restore v3.9's wording, which matches the code.
@gg582
gg582 merged commit 447bd5d into dev Oct 10, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants