diff options
author | benfogle <benfogle@gmail.com> | 2017-11-10 21:03:40 (GMT) |
---|---|---|
committer | Antoine Pitrou <pitrou@free.fr> | 2017-11-10 21:03:40 (GMT) |
commit | 9703f092abc0259926d88c7855afeae4a78afc7d (patch) | |
tree | d19e75bea4faacf58155861dd056f544a584f146 /Modules/_io | |
parent | 4652bf2acc0d1ddabd224efabbfee0c3125da18b (diff) | |
download | cpython-9703f092abc0259926d88c7855afeae4a78afc7d.zip cpython-9703f092abc0259926d88c7855afeae4a78afc7d.tar.gz cpython-9703f092abc0259926d88c7855afeae4a78afc7d.tar.bz2 |
bpo-31976: Fix race condition when flushing a file is slow. (#4331)
Diffstat (limited to 'Modules/_io')
-rw-r--r-- | Modules/_io/bufferedio.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index edc4ba5..1ae7a70 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -347,9 +347,10 @@ _enter_buffered_busy(buffered *self) } #define IS_CLOSED(self) \ + (!self->buffer || \ (self->fast_closed_checks \ ? _PyFileIO_closed(self->raw) \ - : buffered_closed(self)) + : buffered_closed(self))) #define CHECK_CLOSED(self, error_msg) \ if (IS_CLOSED(self)) { \ @@ -1971,14 +1972,17 @@ _io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer) Py_off_t offset; CHECK_INITIALIZED(self) - if (IS_CLOSED(self)) { - PyErr_SetString(PyExc_ValueError, "write to closed file"); - return NULL; - } if (!ENTER_BUFFERED(self)) return NULL; + /* Issue #31976: Check for closed file after acquiring the lock. Another + thread could be holding the lock while closing the file. */ + if (IS_CLOSED(self)) { + PyErr_SetString(PyExc_ValueError, "write to closed file"); + goto error; + } + /* Fast path: the data to write can be fully buffered. */ if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) { self->pos = 0; |