diff options
author | benfogle <benfogle@gmail.com> | 2017-11-10 16:03:40 -0500 |
---|---|---|
committer | Antoine Pitrou <pitrou@free.fr> | 2017-11-10 22:03:40 +0100 |
commit | 9703f092abc0259926d88c7855afeae4a78afc7d (patch) | |
tree | d19e75bea4faacf58155861dd056f544a584f146 /Lib/_pyio.py | |
parent | 4652bf2acc0d1ddabd224efabbfee0c3125da18b (diff) | |
download | cpython-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.py | 19 |
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): |