Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor cancellation of IOCP::OverlappedOperation #14754

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

straight-shoota
Copy link
Member

When an overlapped operation gets cancelled, we still need to wait for completion of the operation (with status ERROR_OPERATION_ABORTED) before it can be freed.
Previously we stored a reference to cancelled operations in a linked list and removed them when complete. This allows continuing executing the fiber directly after the cancellation is triggered, but it's also quite a bit of overhead.
Also it makes it impossible to allocate operations on the stack.

Cancellation is triggered when an operation times out.

The change in this patch is that after a timeout the fiber is suspended again, expecting completion via the event loop. Then the operation can be freed.

src/crystal/system/win32/iocp.cr Outdated Show resolved Hide resolved
event_loop.dequeue(timeout_event)
unless @state.done?
if cancel!
Fiber.suspend
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: maybe explain why we need to suspend the fiber?

Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: we only need to cancel the operation when the fiber awoke from a timeout, so inside the if timeout branch above. The other branch will only ever resume the fiber when the operation was completed.

Or is that to protect against spurious wakeups?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, the cancellation is only relevant when there is a timeout.
Dunno if it's worth keeping it for both branches as a sanity measure 🤔 I don't see any immediate reason to expect a spurious wakeup.

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess there could be use cases for external cancellation, though. We don't need to explicitly cancel pending operations upon closing a handle because IOCP does that automatically. But maybe there could be other situations where we want to cancel a pending operation from a different fiber? 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

None yet

2 participants