Skip to content

fix th .no_wait callback called multi times issue.#209

Open
pomelio wants to merge 1 commit into
mitchellh:mainfrom
pomelio:main
Open

fix th .no_wait callback called multi times issue.#209
pomelio wants to merge 1 commit into
mitchellh:mainfrom
pomelio:main

Conversation

@pomelio

@pomelio pomelio commented Feb 6, 2026

Copy link
Copy Markdown

@mitchellh mitchellh left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

We need a test to validate this. I also like your more detailed comment in your commit:

Fix use-after-free in kqueue no_wait mode
When tick() is called with wait=0 (no_wait mode), it would exit
immediately after processing events without submitting pending
EV_DELETE changes to kqueue. This caused a use-after-free bug:

1. Events complete and callbacks return .disarm
2. DELETEs are queued in local events[] array
3. Completions are marked .dead and recycled
4. tick() exits with wait==0 before submitting DELETEs
5. kqueue still has stale registrations with dead udata pointers
6. Later events (like EOF) arrive with corrupted pointers

Fix: Only exit early if both wait==0 AND changes==0. This ensures
we loop back to submit pending DELETEs via kevent_syscall with
zero timeout before exiting, properly cleaning up kqueue state.

bryanjeal added a commit to bryanjeal/libxev that referenced this pull request Jun 27, 2026
…xt in submit

Bug mitchellh#209: kqueue tick(0) EV_DELETE flush
- Changed early exit condition from 'if (wait == 0) break' to
  'if (wait == 0 and changes == 0) break' so pending EV_DELETE
  kevent changes from the event-processing loop are flushed
  before tick(0) returns.

Bug mitchellh#170: rearm state correction
- When a non-kqueue completion (close, shutdown, threadpool
  fallback) returns .rearm, set flags.state to .adding before
  pushing to the submissions queue. Previously .dead state
  caused submit() to route through stop_completion (cancel)
  instead of start() (resubmit).

Issue mitchellh#169: defensive next-pointer clear in submit()
- Explicitly clear c.next before push to completions queue
  when processing kevent-returned events in submit(). This
  prevents an assertion failure if a completion is present
  in multiple queues concurrently (race condition).
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