summaryrefslogtreecommitdiff
path: root/Lib/_pyio.py
diff options
context:
space:
mode:
authorbenfogle <benfogle@gmail.com>2017-11-10 16:03:40 -0500
committerAntoine Pitrou <pitrou@free.fr>2017-11-10 22:03:40 +0100
commit9703f092abc0259926d88c7855afeae4a78afc7d (patch)
treed19e75bea4faacf58155861dd056f544a584f146 /Lib/_pyio.py
parent4652bf2acc0d1ddabd224efabbfee0c3125da18b (diff)
downloadcpython-git-9703f092abc0259926d88c7855afeae4a78afc7d.tar.gz
bpo-31976: Fix race condition when flushing a file is slow. (#4331)
Diffstat (limited to 'Lib/_pyio.py')
-rw-r--r--Lib/_pyio.py19
1 files changed, 17 insertions, 2 deletions
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index 6833883dad..adf5d0ecbf 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -1188,11 +1188,11 @@ class BufferedWriter(_BufferedIOMixin):
return self.raw.writable()
def write(self, b):
- if self.closed:
- raise ValueError("write to closed file")
if isinstance(b, str):
raise TypeError("can't write str to binary stream")
with self._write_lock:
+ if self.closed:
+ raise ValueError("write to closed file")
# XXX we can implement some more tricks to try and avoid
# partial writes
if len(self._write_buf) > self.buffer_size:
@@ -1253,6 +1253,21 @@ class BufferedWriter(_BufferedIOMixin):
self._flush_unlocked()
return _BufferedIOMixin.seek(self, pos, whence)
+ def close(self):
+ with self._write_lock:
+ if self.raw is None or self.closed:
+ return
+ # We have to release the lock and call self.flush() (which will
+ # probably just re-take the lock) in case flush has been overridden in
+ # a subclass or the user set self.flush to something. This is the same
+ # behavior as the C implementation.
+ try:
+ # may raise BlockingIOError or BrokenPipeError etc
+ self.flush()
+ finally:
+ with self._write_lock:
+ self.raw.close()
+
class BufferedRWPair(BufferedIOBase):