Skip to content

fix(io): reject blocking epoll connects#999

Merged
Coldwings merged 1 commit into
mainfrom
fix/epoll-connect-require-nonblocking
Jul 21, 2026
Merged

fix(io): reject blocking epoll connects#999
Coldwings merged 1 commit into
mainfrom
fix/epoll-connect-require-nonblocking

Conversation

@Coldwings

Copy link
Copy Markdown
Owner

Description

Require descriptors submitted to the epoll connect backend to already have O_NONBLOCK. This prevents the backend worker from executing a potentially blocking connect(2) while preserving caller ownership of the shared open-file-description flags.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • Documentation (changes to documentation, comments, or examples)
  • Tests (adding or modifying tests)

Related Issues

Closes #997
Related to #985

Changes Made

Core Changes

  • Check F_GETFL before invoking connect(2) in the epoll backend.
  • Queue exact negative errno on flag lookup failure and -EINVAL for a valid blocking descriptor.
  • Leave descriptor flags unchanged because O_NONBLOCK belongs to the shared open-file description.
  • Add deterministic regressions for blocking sockets and F_GETFL failure.
  • Document the cross-backend caller contract and update the changelog.

API Changes (if applicable)

No signature changes. The epoll connect backend now explicitly rejects descriptors that do not satisfy its existing asynchronous-use precondition.

Testing

Unit Tests

  • Added new tests for the changes
  • All tests pass locally

Test Results

Static review only; local builds and tests were intentionally not run. GitHub Actions is the executable validation source for this PR.

Checklist

Code Quality

  • My code follows the project's code style
  • I have added/updated comments for complex logic
  • I have removed any debug code, TODOs, or commented-out code

Documentation

  • I have updated documentation
  • I have updated API documentation

Testing

  • I have added tests that prove the fix is effective
  • New and existing unit tests pass locally with my changes
  • I have tested with ASAN and TSAN

Compatibility

  • My changes are backward compatible
  • I have considered the impact on existing users
  • I have updated CHANGELOG.md

Additional Notes

Two independent static reviews passed against the exact rebased head before opening this PR. No local compilation or test execution was performed.

Reviewer Guidance

Areas requiring special attention:

  • Epoll worker non-blocking guarantee and exact errno propagation.
  • Caller ownership of O_NONBLOCK across duplicated descriptors.
  • Consistency of the documented epoll/io_uring contract boundary.

Copilot AI review requested due to automatic review settings July 21, 2026 15:11

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Coldwings

Copy link
Copy Markdown
Owner Author

Independent current-head review summary (ed3e79fc7e42b4d3a8048ae88640619123cb32e1)

Two read-only reviewers examined this exact head against 7b12fc55a7b0c02e0f2e7a7933d39e2711d84d49 from complementary backend/lifecycle and public-contract perspectives. Both reported PASS with no blocker, major, or minor findings.

Verified points:

  • The epoll worker performs F_GETFL before connect(2), preserves exact lookup errno, and rejects a blocking descriptor with EINVAL through the normal deferred completion path.
  • The backend does not mutate O_NONBLOCK, avoiding side effects on duplicated descriptors that share the same open-file description.
  • Pending-operation accounting and completion ownership remain balanced for both rejection paths.
  • The io_uring distinction and the caller obligation to keep O_NONBLOCK set through epoll completion are documented consistently.
  • Focused tests independently cover a valid blocking socket and an invalid descriptor, alongside existing nonblocking success and refused-connect coverage.
  • The rebased patch is range-equivalent to the previously reviewed patch; the worktree and whitespace check were clean.

Review method: static inspection only; no local build or tests were run. GitHub Actions remains the executable validation gate.

@Coldwings
Coldwings merged commit 17b4350 into main Jul 21, 2026
10 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.

[Bug] epoll async_connect can block a worker on a blocking socket

2 participants