@@ -623,32 +623,34 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, int mode)
623623 if (mode == PDA_WRITE)
624624 {
625625 /* If there is anything available in the pipe buffer then signal
626- that. This means that a pipe could still block since you could
627- be trying to write more to the pipe than is available in the
628- buffer but that is the hazard of select().
629-
630- Note that WriteQuotaAvailable is unreliable.
631-
632- Usually WriteQuotaAvailable on the write side reflects the space
633- available in the inbound buffer on the read side. However, if a
634- pipe read is currently pending, WriteQuotaAvailable on the write side
635- is decremented by the number of bytes the read side is requesting.
636- So it's possible (even likely) that WriteQuotaAvailable is 0, even
637- if the inbound buffer on the read side is not full. This can lead to
638- a deadlock situation: The reader is waiting for data, but select
639- on the writer side assumes that no space is available in the read
640- side inbound buffer.
641-
642- Consequentially, there are two possibilities when WriteQuotaAvailable
643- is 0. One is that the buffer is really full. The other is that the
644- reader is currently trying to read the pipe and it is pending.
645- In the latter case, the fact that the reader cannot read the data
646- immediately means that the pipe is empty. In the former case,
647- NtSetInformationFile() in set_pipe_non_blocking(true) will fail
648- with STATUS_PIPE_BUSY, while it succeeds in the latter case.
649- Therefore, we can distinguish these cases by calling set_pipe_non_
650- blocking(true). If it returns success, the pipe is empty, so we
651- return the pipe buffer size. Otherwise, we return 0. */
626+ that. This means that a pipe could still block since you could
627+ be trying to write more to the pipe than is available in the
628+ buffer but that is the hazard of select().
629+
630+ Note that WriteQuotaAvailable is unreliable.
631+
632+ Usually WriteQuotaAvailable on the write side reflects the space
633+ available in the inbound buffer on the read side. However, if a
634+ pipe read is currently pending, WriteQuotaAvailable on the write side
635+ is decremented by the number of bytes the read side is requesting.
636+ So it's possible (even likely) that WriteQuotaAvailable is less than
637+ actual space available in the pipe, even if the inbound buffer is
638+ empty. This can lead to a deadlock situation: The reader is waiting
639+ for data, but select on the writer side assumes that no space is
640+ available in the read side inbound buffer.
641+
642+ Consequentially, there are two possibilities when WriteQuotaAvailable
643+ is less than pipe size. One is that the buffer is really not empty.
644+ The other is that the reader is currently trying to read the pipe
645+ and it is pending.
646+ In the latter case, the fact that the reader cannot read the data
647+ immediately means that the pipe is empty. In the former case,
648+ NtSetInformationFile() in set_pipe_non_blocking(true) will fail
649+ with STATUS_PIPE_BUSY, while it succeeds in the latter case.
650+ Therefore, we can distinguish these cases by calling set_pipe_non_
651+ blocking(true). If it returns success, the pipe is empty, so we
652+ return the pipe buffer size. Otherwise, we return the value of
653+ WriteQuotaAvailable as is. */
652654 if (fh->get_device () == FH_PIPEW
653655 && fpli.WriteQuotaAvailable < fpli.InboundQuota )
654656 {
0 commit comments