-
Notifications
You must be signed in to change notification settings - Fork 465
Switch Win32 pipes to PIPE_WAIT with sentinel bufsize #854
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
Switch Win32 pipes to PIPE_WAIT with sentinel bufsize #854
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm comfortable with this fix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking at this! Just a comment, no opinion on the change.
b0ea38b
to
93c4bcd
Compare
93c4bcd
to
b2544fe
Compare
@swift-ci please test |
@swift-ci please test Windows platform |
Fixes #820 . There is a lot of useful context in this issue, which I will partially reproduce below.
I have an alternate PR that fixes this problem in a less fundamental way, but without a small requirements change to libdispatch which I describe below: #853.
Problem description, copied from the aforementioned PR:
The real issue here is the inability to distinguish on the write side of a pipe between the following cases:
This PR implements the same switch back to
PIPE_WAIT
as in #853, but uses a trick to enableWriteQuotaAvailable == 1
to be used as a sentinel value to distinguish the "output buffer is full" case. By always leaving a free byte of space in the buffer when writing, the only way thatWriteQuotaAvailable == 0
can happen is if a reader has requested a full buffer's worth of data.This means that when we see
WriteQuotaAvailable == 1
, we know the output buffer is "full" and not attempt to perform a blocking write.The downside to this approach is that we can no longer serially write-then-read a full buffer's worth of data, because the write will not finish writing the last byte until reading has commenced. I don't see this scenario ever arising in practice: if you are trying to move data serially from one buffer to another on the same thread, there are better ways to do that than through a libdispatch pipe. But regardless, this requirement is implicit due to the serial nature of the
dispatch_io_pipe
tests. If if is acceptable to relax this requirement from "writes of<=bufSize
are guaranteed to complete in the absence of a reader" to "writes of<bufSize
are guaranteed to complete in the absence of a reader" then I think this solution is more robust than just #853.It's entirely possible I'm missing some good reason why this requirement is there though, in which case I think #853 should be acceptable.
cc @compnerd