-
Notifications
You must be signed in to change notification settings - Fork 732
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
windows: support custom completion port integrations #1047
Comments
Related #526. |
I think this is related to a |
Punting to v1.0. |
@piscisaureus I have a question re: this proposal. My understanding is that, when an OVERLAPPED operation is submitted to the OS, the OS needs "ownership" of the pointer. Ownership is returned back to the caller when the operation is completed and the overlapped is received during a "poll". This implies that the selector needs to know about "in-flight" operations. This needs to happen so that when the It gets a bit more complicated with "read" like operations that may not complete... in those cases, Do you have thoughts on how to model this? |
@Thomasdezeeuw please assign this issue to me, will start working on it. |
@dtacalau before writing code we should have a solid proposal in place. I think bert’s sketch is a good starting point but we want to figure out the answers to my previous comment as well as a nice rust API to expose. |
Make sure the Overlapped is wrapped (either directly or indirectly) wrapped in an Arc. When an async I/O operation is successfully started (and you know the kernel now implicitly owns the OVERLAPPED) you artificially increase the Arc's reference count by cloning and forgetting the Arc. When the operation completes and you receive a OVERLAPPED* from GetQueuedCompletionStatus, do some pointer math if necessary to get back at the wrapper struct, and then transmute/cast that back to an Arc, thereby effectively reversing the std::mem::forget::() we did after starting the operation. I think the most elegant way was in this (rejected) patch: |
@piscisaureus that patch, with modifications, made it into the code base: mio/src/sys/windows/selector.rs Lines 288 to 301 in 3ebce3e
|
Instead of making an API to hook into IOCP, would it be plausible to provide bindings to all the IOCP compatible types? The various types could be guarded w/ feature flags. |
Not blocking a v1.0 release. |
We have/had a partially working solution in #1345, but there is not enough interest to make this work. Because of this I'm closing this. |
The new "wepoll" strategy is great for sockets but it makes it impossible to use the thread's I/O completion port for other purposes.
I would suggest to add a low-level "plugin" system so that other crates can share the completion port for different purposes.
This could be used for supporting named pipes and files, which can use overlapped I/O but their APIs work differently; more exotic examples are ReadDirectoryChangesW (file change notifications), GetAddrInfoExW (async DNS name lookup), and Job Objects (notifications about child processes).
Job objects in particular are exotic in that windows will send messages to the completion port where
lpOverlapped
does not actually point to astruct OVERLAPPED
, but rather contains an indication of the event that happened.So I would propose to to "switch" based on the
lpCompletionKey
value. The most simple solution would be to store a function pointer in it which receives the raw completion information, e.g.fn handle_completion(&OVERLAPPED_ENTRY)
.To illustrate what I mean, here's a crude prototype: piscisaureus@ac40cd7
Notice how the
Selector
is no longer knows anything aboutWake
events.They work simply because the
lpCompletionKey
contains an appropriate function pointerThe text was updated successfully, but these errors were encountered: