Skip to content

refactor(fasthttp): make both Linux (epoll) and BSD (kqueue) backends asynchronous#27477

Open
guweigang wants to merge 14 commits into
vlang:masterfrom
guweigang:fix-fasthttp-bsd
Open

refactor(fasthttp): make both Linux (epoll) and BSD (kqueue) backends asynchronous#27477
guweigang wants to merge 14 commits into
vlang:masterfrom
guweigang:fix-fasthttp-bsd

Conversation

@guweigang

@guweigang guweigang commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR refactors both the Linux (epoll) and BSD (kqueue) backends of the fasthttp module to be fully asynchronous using the LoopCommand channel pattern and spawn coroutines.

It resolves the upstream review comments regarding the BSD kqueue async PR (#27477) by:

  1. P1 (Linux block/hang on loopback request): The Linux backend previously processed requests synchronously inline within the main epoll event loop thread, blocking the loop and causing timeouts for nested loopback requests (e.g. test_handler_can_make_loopback_request_to_same_server). We refactored vlib/fasthttp/fasthttp_linux.v to decouple request handling into async coroutines, allowing loopback requests to process without blocking.
  2. P2 (Connection lifetime race under .manual takeover): For .manual takeover mode, we deferred the server.end_request() call in both backends until the event loop has successfully deregistered the fd and cleaned tracking maps, avoiding early socket closures during server shutdown.
  3. Keep-alive epoll re-registration: Fixed a bug where keep-alive connections could lose epoll registration after their first request if the write completed instantly (i.e. epollout_was_armed was false). The socket is now unconditionally re-added to the epoll listen mask on keep-alive completion.

Key Changes

  • vlib/fasthttp/fasthttp_linux.v:
    • Added LoopCommandKind and LoopCommand structs.
    • Decoupled request processing into process_request_async.
    • Implemented drain_loop_commands to safely process commands and update connection/write maps in the main thread.
    • Unconditionally re-registers sockets to epoll for keep-alive connections on write completion.
  • vlib/fasthttp/fasthttp_bsd.c.v:
    • Deferred server.end_request() under .manual_takeover to the loop command handler.
  • vlib/fasthttp/fasthttp_test.v:
    • Re-enabled the loopback nested request test for Linux ($if linux || bsd).

Verification

  • Tested locally on macOS (BSD kqueue backend): 2 passed, 2 total.
  • Tested in a Linux (Debian aarch64) container (Linux epoll backend): 2 passed, 2 total (including nested loopback test).

@guweigang guweigang marked this pull request as ready for review June 17, 2026 07:47
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.

@guweigang

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@JalonSolov

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b48a62cf56

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread vlib/fasthttp/fasthttp_test.v
Comment thread vlib/fasthttp/fasthttp_bsd.c.v Outdated
@guweigang guweigang changed the title fasthttp: process BSD requests outside the kqueue loop refactor(fasthttp): make both Linux (epoll) and BSD (kqueue) backends asynchronous Jun 19, 2026
@medvednikov

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 68402cd3b2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread vlib/fasthttp/fasthttp_linux.v
Comment thread vlib/fasthttp/fasthttp_linux.v Outdated
@JalonSolov

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5de24dda04

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread vlib/fasthttp/fasthttp_linux.v Outdated
@guweigang

Copy link
Copy Markdown
Contributor Author

Addressed the latest review findings:

  • allocate Linux async write state independently from the spawned thread's prealloc scope
  • complete BSD reusable-request accounting on the event-loop thread, avoiding the shutdown race
  • wake epoll/kqueue immediately after workers enqueue loop commands
  • add Linux and BSD regression coverage for lifecycle ownership and poll wakeups

Validation:

  • macOS: fasthttp module suite: 3 passed, 1 Linux-only test skipped
  • macOS prealloc fasthttp test: passed
  • Ubuntu ARM64 with VFLAGS='-gc none -cc gcc': fasthttp module suite: 3 passed, 1 BSD-only test skipped
  • Ubuntu ARM64 prealloc regression set: 2/2 passed

@JalonSolov

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: b7a287ce4e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@JalonSolov

Copy link
Copy Markdown
Collaborator

linux fasthttp regression test is failing...

https://github.com/vlang/v/actions/runs/27902688632/job/82565746225?pr=27477#step:14:36

@guweigang

Copy link
Copy Markdown
Contributor Author

linux fasthttp regression test is failing...

https://github.com/vlang/v/actions/runs/27902688632/job/82565746225?pr=27477#step:14:36

Got that, I will fix this

@guweigang

Copy link
Copy Markdown
Contributor Author

Addressed the remaining Linux CI failures:

  • split the Linux prealloc regression from the regular regression suite; the prealloc-only test now uses linux && !tinyc, since TCC does not implement _Thread_local
  • keep the fasthttp veb user context in the request heap/arena so manual-takeover work can safely outlive the async request worker
  • remove the duplicate EPOLL_CTL_DEL during manual takeover
  • add a focused regression proving the prealloc write state remains valid after its worker exits

Root cause of the musl SSE crash: the SSE child thread received a pointer to a user context stored on the async parent worker's stack. With -gc none/musl, the parent exited first and the child dereferenced the retired stack. GDB reproduced the crash in veb.sse.start_connection; the heap/arena-backed context fixes that ownership violation.

Validation:

  • macOS SSE test: passed
  • macOS fasthttp module: 3 passed, 2 Linux-only tests skipped
  • Ubuntu ARM64 GCC with -gc none: regular, prealloc, and existing fasthttp tests passed
  • Ubuntu ARM64 musl-gcc with -gc none: SSE passed (previously deterministic SIGSEGV/code 139)
  • Ubuntu ARM64 TCC: regular Linux regression passed; prealloc regression correctly skipped

@JalonSolov

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3f5a1e5e5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread vlib/fasthttp/fasthttp_bsd.c.v Outdated
@guweigang

guweigang commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Updated for the latest P2 review.

Changes:

  • BSD /kqueue manual takeover cleanup now verifies clients[fd] still points at the stale command's Conn before deleting the map entry and kqueue events. This avoids deleting events for a newly accepted connection that reused the same fd after user code closed the takeover socket.
  • added a BSD regression test covering the reused-fd stale manual_takeover command case.
  • merged latest upstream/master into the PR branch.

Validation:

  • macOS: ./v -g -keepc -o ./vnew cmd/v
  • macOS: ./vnew test vlib/fasthttp/fasthttp_bsd_regression_test.c.v -> 1 passed
  • Linux Orb Ubuntu with VFLAGS='-gc none -cc gcc': ./v -g -keepc -o ./vnew cmd/v
  • Linux Orb Ubuntu: ./vnew test vlib/fasthttp/fasthttp_linux_regression_test.v vlib/fasthttp/fasthttp_linux_prealloc_regression_test.v vlib/fasthttp/fasthttp_test.v -> 3 passed

@JalonSolov

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dd86d21b27

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread vlib/fasthttp/fasthttp_linux.v Outdated
@guweigang

guweigang commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

Updated for the latest P2 review.

Changes:

  • Linux fasthttp now tags accepted client fds with a per-connection generation.
  • async loop commands carry that generation, and manual_takeover cleanup only deletes fd-keyed client state when the queued command still matches the currently tracked connection.
  • added Linux regression coverage for a stale manual_takeover command arriving after the same fd has been reused, preserving the new connection's buffer/read-start/closing state.
  • merged latest upstream/master into the branch before pushing.

Validation:

  • macOS: ./v -g -keepc -o ./vnew cmd/v
  • macOS: ./vnew test vlib/fasthttp/fasthttp_bsd_regression_test.c.v vlib/fasthttp/fasthttp_linux_regression_test.v -> 1 passed, 1 skipped (Linux-only)
  • Linux Orb Ubuntu with VFLAGS='-gc none -cc gcc': ./v -g -keepc -o ./vnew cmd/v
  • Linux Orb Ubuntu: ./vnew test vlib/fasthttp/fasthttp_linux_regression_test.v vlib/fasthttp/fasthttp_linux_prealloc_regression_test.v vlib/fasthttp/fasthttp_test.v -> 3 passed

@JalonSolov

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.

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.

3 participants