summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2010-10-28 14:50:57 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2010-10-28 14:50:57 (GMT)
commit638cee62d5f25abf29290825f1600728f79da002 (patch)
treeb3449f45ffa87d16317c4b292a3d6702efb40681
parent658370e72c6a3fe5fdeb3592278fc29eb0e5a7e3 (diff)
downloadcpython-638cee62d5f25abf29290825f1600728f79da002.zip
cpython-638cee62d5f25abf29290825f1600728f79da002.tar.gz
cpython-638cee62d5f25abf29290825f1600728f79da002.tar.bz2
Issue #9295: Fix a crash under Windows when calling close() on a file
object with custom buffering from two threads at once.
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/fileobject.c6
2 files changed, 9 insertions, 0 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index fa41945..665271e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -63,6 +63,9 @@ Core and Builtins
Library
-------
+- Issue #9295: Fix a crash under Windows when calling close() on a file
+ object with custom buffering from two threads at once.
+
- Issue #5027: The standard ``xml`` namespace is now understood by
xml.sax.saxutils.XMLGenerator as being bound to
http://www.w3.org/XML/1998/namespace. Patch by Troy J. Farrell.
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 2647b54..974d642 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -423,6 +423,7 @@ close_the_file(PyFileObject *f)
int sts = 0;
int (*local_close)(FILE *);
FILE *local_fp = f->f_fp;
+ char *local_setbuf = f->f_setbuf;
if (local_fp != NULL) {
local_close = f->f_close;
if (local_close != NULL && f->unlocked_count > 0) {
@@ -446,10 +447,15 @@ close_the_file(PyFileObject *f)
* called. */
f->f_fp = NULL;
if (local_close != NULL) {
+ /* Issue #9295: must temporarily reset f_setbuf so that another
+ thread doesn't free it when running file_close() concurrently.
+ Otherwise this close() will crash when flushing the buffer. */
+ f->f_setbuf = NULL;
Py_BEGIN_ALLOW_THREADS
errno = 0;
sts = (*local_close)(local_fp);
Py_END_ALLOW_THREADS
+ f->f_setbuf = local_setbuf;
if (sts == EOF)
return PyErr_SetFromErrno(PyExc_IOError);
if (sts != 0)