From 9703f092abc0259926d88c7855afeae4a78afc7d Mon Sep 17 00:00:00 2001 From: benfogle Date: Fri, 10 Nov 2017 16:03:40 -0500 Subject: bpo-31976: Fix race condition when flushing a file is slow. (#4331) --- Lib/_pyio.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'Lib/_pyio.py') 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): -- cgit v1.2.1