(I have now subscribed to the list to get everyone's replies. Sorry for breaking the message thread.)
Eric Blake wrote: > On 02/20/2015 01:21 PM, Lasse Collin wrote: > > The above Cygwin behavior would make it very easy to add a > > workaround to xz for the pipe-data-loss problem: simply don't clear > > O_NONBLOCK on stdout. However, I wonder if it is a bug in Cygwin > > that the changes to file status flags aren't seen via other file > > descriptors that refer to the same file description. If it is a > > bug, then the workaround idea will cause trouble in the future when > > the bug in Cygwin gets fixed. > > Yeah, the fact that cygwin is buggy with respect to POSIX may break > any workaround you add if cygwin is later patched. OK. I think I will keep stdout in blocking mode in xz on Cygwin for now. The race condition in signal handling is a very minor issue compared to data loss. Thomas Wolff wrote: > 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. I agree that it's better than losing data even though it has some problems. Blocking F_SETFL can cause a deadlock since it is valid to do this from a single thread: 1. Create a pipe in non-blocking mode. 2. Write up to PIPE_BUF bytes to the pipe. 3. Set pipe to blocking mode. 4. Read from the pipe. I don't know why a program would do that, so maybe it's not a problem in practice. Even if it is a problem, a deadlock should be easier to debug than silent data loss. What should be done if the thread blocked in F_SETFL receives a signal? Usually blocking syscalls can be interrupted by signals if SA_RESTART isn't used. Looking at POSIX and Linux fcntl() man pages, the possibility of EINTR is mentioned for specific commands and F_SETFL isn't among them. It sounds likely that applications aren't prepared to restart F_SETFL (at least xz isn't), and using EINTR would lead to data loss, although it would no longer be silent data loss since it can be detected from fcntl's return value. It's worth noting that the interrupting signal doesn't necessarily come from a user; it may be e.g. SIGALRM that was requested via alarm(). On the other hand, if the fcntl() call is restarted after a signal even when SA_RESTART isn't used, a program may become unresponsive to signals. Even then this sounds less bad than unexpected EINTR (assuming that applications aren't prepared to restart F_SETFL). Alternative idea: Would there be a significant downside if Cygwin remembered if non-blocking mode was enabled at some point and close() would use that flag instead of the current (non)blocking status to determine if the background thread hack should be used? -- Lasse Collin | IRC: Larhzu @ IRCnet & Freenode -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple