This is the mail archive of the
mailing list for the Cygwin project.
Re: Clearing O_NONBLOCK from a pipe may lose data
- From: Thomas Wolff <towo at towo dot net>
- To: cygwin at cygwin dot com
- Date: Fri, 20 Feb 2015 08:56:31 +0100
- Subject: Re: Clearing O_NONBLOCK from a pipe may lose data
- Authentication-results: sourceware.org; auth=none
- References: <20150218220859 dot 1e8f8b19 at tukaani dot org> <20150219095147 dot GC26084 at calimero dot vinschen dot de> <54E660F1 dot 3040509 at towo dot net> <145631367 dot 20150220024700 at yandex dot ru>
Am 20.02.2015 um 00:47 schrieb Andrey Repin:
Greetings, Thomas Wolff!
Am 19.02.2015 um 10:51 schrieb Corinna Vinschen:
On Feb 18 22:08, Lasse Collin wrote:
(Please Cc me when replying, I'm not subscribed to the list.)
I suspect that there is a bug in Cygwin:
1. Create a pipe with both ends in blocking mode (O_NONBLOCK
is not set).
2. The writer sets its end to non-blocking mode.
3. The writer writes to the pipe.
4. The writer restores its end of the pipe to blocking mode
before the reader has read anything from the pipe.
5. The writer closes its end of the pipe.
6. The reader reads from the pipe in blocking mode. The last
bytes written by the writer never appear at the reader,
thus data is silently lost.
Omitting the step 4 above makes the problem go away.
I can imagine. A few years back, when changing the pipe code to
using overlapped IO, we stumbled over a problem in Windows. When
closing an overlapped pipe while I/O is still ongoing, Windows
simply destroys the pipe buffers without flushing the data to the
reader. This is not much of a problem for blocking IO, but it
obviously is for non-blocking.
The workaround for this behaviour is this: If the pipe is closed, and
this is the writing side of a nonblocking pipe, a background thread gets
started which keeps the overlapped structure open and continues to wait
for IO completion (i.e. the data has been sent to the reader).
However, if you switch back to blocking before closing the pipe, the
aforementioned mechanism does not kick in.
Could not "switching back to blocking" simply be handled like closing as
far as the waiting is concerned,
thus effectively flushing the pipe buffer?
You can't "just flush" it, if the receiving end isn't reading from it.
By flushing I meant actually waiting until it's been consumed at the
other end in this case, if that's technically feasible.
I see no strict requirement that the fcntl call removing O_NONBLOCK from
a file descriptor should itself still be handled as nonblocking (it can
well be argued that the flag is changed first and then the call is
allowed to block) - and even if this were not proper it is certainly
more acceptable than losing data.
Diese E-Mail wurde von Avast Antivirus-Software auf Viren geprüft.
Problem reports: http://cygwin.com/problems.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple