Skip to content

Commit 5f3825b

Browse files
committed
Fix thread safety in StringIO.
1 parent 0f866cb commit 5f3825b

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

Modules/_io/stringio.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwarg
7979
static int
8080
resize_buffer(stringio *self, size_t size)
8181
{
82+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
8283
/* Here, unsigned types are used to avoid dealing with signed integer
8384
overflow, which is undefined in C. */
8485
size_t alloc = self->buf_size;
@@ -131,6 +132,7 @@ resize_buffer(stringio *self, size_t size)
131132
static PyObject *
132133
make_intermediate(stringio *self)
133134
{
135+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
134136
PyObject *intermediate = PyUnicodeWriter_Finish(self->writer);
135137
self->writer = NULL;
136138
self->state = STATE_REALIZED;
@@ -153,6 +155,7 @@ make_intermediate(stringio *self)
153155
static int
154156
realize(stringio *self)
155157
{
158+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
156159
Py_ssize_t len;
157160
PyObject *intermediate;
158161

@@ -188,6 +191,7 @@ realize(stringio *self)
188191
static Py_ssize_t
189192
write_str(stringio *self, PyObject *obj)
190193
{
194+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
191195
Py_ssize_t len;
192196
PyObject *decoded = NULL;
193197

@@ -355,6 +359,7 @@ _io_StringIO_read_impl(stringio *self, Py_ssize_t size)
355359
static PyObject *
356360
_stringio_readline(stringio *self, Py_ssize_t limit)
357361
{
362+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
358363
Py_UCS4 *start, *end, old_char;
359364
Py_ssize_t len, consumed;
360365

@@ -404,8 +409,9 @@ _io_StringIO_readline_impl(stringio *self, Py_ssize_t size)
404409
}
405410

406411
static PyObject *
407-
stringio_iternext(PyObject *op)
412+
stringio_iternext_lock_held(PyObject *op)
408413
{
414+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
409415
PyObject *line;
410416
stringio *self = stringio_CAST(op);
411417

@@ -441,6 +447,16 @@ stringio_iternext(PyObject *op)
441447
return line;
442448
}
443449

450+
static PyObject *
451+
stringio_iternext(PyObject *op)
452+
{
453+
PyObject *res;
454+
Py_BEGIN_CRITICAL_SECTION(op);
455+
res = stringio_iternext_lock_held(op);
456+
Py_END_CRITICAL_SECTION();
457+
return res;
458+
}
459+
444460
/*[clinic input]
445461
@critical_section
446462
_io.StringIO.truncate

0 commit comments

Comments
 (0)