diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2015-02-24 11:05:02 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2015-02-24 11:05:02 +0000 |
commit | 59076540bce2380bade31edba78b8dd421a03d3c (patch) | |
tree | 5a545da9009afa80211d20b3bd45e9728f9abc9e /winsup/cygwin/fhandler.cc | |
parent | f8a6c963061eb9dcaa0bc0582e0e31cdfcec0d3c (diff) | |
download | cygnal-59076540bce2380bade31edba78b8dd421a03d3c.tar.gz cygnal-59076540bce2380bade31edba78b8dd421a03d3c.tar.bz2 cygnal-59076540bce2380bade31edba78b8dd421a03d3c.zip |
* fhandler.h (class fhandler_base): Add was_nonblocking status flag.
* fhandler.cc (fhandler_base::set_flags): Set was_nonblocking if the
O_NONBLOCK flag has been specified.
(fhandler_base_overlapped::close): Check for was_nonblocking instead
of for is_nonblocking. Explain why.
(fhandler_base::set_nonblocking): Set was_nonblocking if noblocking
mode gets enabled.
Diffstat (limited to 'winsup/cygwin/fhandler.cc')
-rw-r--r-- | winsup/cygwin/fhandler.cc | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 8444d4abc..6f024da32 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1,7 +1,7 @@ /* fhandler.cc. See console.cc for fhandler_console functions. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc. + 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Red Hat, Inc. This file is part of Cygwin. @@ -205,6 +205,8 @@ fhandler_base::set_flags (int flags, int supplied_bin) bin = wbinary () || rbinary () ? O_BINARY : O_TEXT; openflags = flags | bin; + if (openflags & O_NONBLOCK) + was_nonblocking (true); bin &= O_BINARY; rbinary (bin ? true : false); @@ -1242,8 +1244,13 @@ fhandler_base_overlapped::close () int res; int writer = (get_access () & GENERIC_WRITE); /* Need to treat non-blocking I/O specially because Windows appears to - be brain-dead */ - if (writer && is_nonblocking () && has_ongoing_io ()) + be brain-dead. We're checking here if the descriptor was ever set + to nonblocking, rather than checking if it's nonblocking at close time. + The reason is that applications may switch back to blocking (for the + sake of some other application accessing this descriptor) without + performaing any further I/O. These applications would suffer data + loss, which this workaround is trying to fix. */ + if (writer && was_nonblocking () && has_ongoing_io ()) { clone (HEAP_3_FHANDLER)->check_later (); res = 0; @@ -1629,6 +1636,8 @@ fhandler_base::set_nonblocking (int yes) int current = openflags & O_NONBLOCK_MASK; int new_flags = yes ? (!current ? O_NONBLOCK : current) : 0; openflags = (openflags & ~O_NONBLOCK_MASK) | new_flags; + if (new_flags) + was_nonblocking (true); } int |