Skip to content

Commit 55ea54d

Browse files
committed
Use a critical section for close()
1 parent efe9f87 commit 55ea54d

File tree

2 files changed

+47
-8
lines changed

2 files changed

+47
-8
lines changed

Objects/clinic/genobject.c.h

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/genobject.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@
1717

1818
#include "pystats.h"
1919

20+
/*[clinic input]
21+
class generator "PyGenObject *" "&PyGen_Type"
22+
[clinic start generated code]*/
23+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a6c98fdc710c6976]*/
24+
25+
#include "clinic/genobject.c.h"
26+
2027
// Forward declarations
21-
static PyObject* gen_close(PyObject *, PyObject *);
2228
static PyObject* async_gen_asend_new(PyAsyncGenObject *, PyObject *);
2329
static PyObject* async_gen_athrow_new(PyAsyncGenObject *, PyObject *);
2430

@@ -119,7 +125,7 @@ _PyGen_Finalize(PyObject *self)
119125
_PyErr_WarnUnawaitedCoroutine((PyObject *)gen);
120126
}
121127
else {
122-
PyObject *res = gen_close((PyObject*)gen, NULL);
128+
PyObject *res = gen_close(gen, NULL);
123129
if (res == NULL) {
124130
if (PyErr_Occurred()) {
125131
PyErr_WriteUnraisable(self);
@@ -335,7 +341,7 @@ gen_close_iter(PyObject *yf)
335341
PyObject *retval = NULL;
336342

337343
if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) {
338-
retval = gen_close((PyObject *)yf, NULL);
344+
retval = gen_close((PyGenObject *)yf, NULL);
339345
if (retval == NULL)
340346
return -1;
341347
}
@@ -389,8 +395,16 @@ _PyGen_yf(PyGenObject *gen)
389395
return res;
390396
}
391397

398+
/*[clinic input]
399+
@critical_section
400+
generator.close as gen_close
401+
402+
raise GeneratorExit inside generator.
403+
[clinic start generated code]*/
404+
392405
static PyObject *
393-
gen_close(PyObject *self, PyObject *args)
406+
gen_close_impl(PyGenObject *self)
407+
/*[clinic end generated code: output=2d7adf450173059c input=6c40e85559b6f098]*/
394408
{
395409
PyGenObject *gen = _PyGen_CAST(self);
396410

@@ -624,7 +638,11 @@ gen_throw(PyGenObject *gen, PyObject *const *args, Py_ssize_t nargs)
624638
else if (nargs == 2) {
625639
val = args[1];
626640
}
627-
return _gen_throw(gen, 1, typ, val, tb);
641+
PyObject *res;
642+
Py_BEGIN_CRITICAL_SECTION(gen);
643+
res = _gen_throw(gen, 1, typ, val, tb);
644+
Py_END_CRITICAL_SECTION();
645+
return res;
628646
}
629647

630648

@@ -856,7 +874,7 @@ PyDoc_STRVAR(sizeof__doc__,
856874
static PyMethodDef gen_methods[] = {
857875
{"send", gen_send, METH_O, send_doc},
858876
{"throw", _PyCFunction_CAST(gen_throw), METH_FASTCALL, throw_doc},
859-
{"close", gen_close, METH_NOARGS, close_doc},
877+
GEN_CLOSE_METHODDEF
860878
{"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__},
861879
{"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
862880
{NULL, NULL} /* Sentinel */
@@ -1217,7 +1235,7 @@ PyDoc_STRVAR(coro_close_doc,
12171235
static PyMethodDef coro_methods[] = {
12181236
{"send", gen_send, METH_O, coro_send_doc},
12191237
{"throw",_PyCFunction_CAST(gen_throw), METH_FASTCALL, coro_throw_doc},
1220-
{"close", gen_close, METH_NOARGS, coro_close_doc},
1238+
GEN_CLOSE_METHODDEF
12211239
{"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__},
12221240
{"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
12231241
{NULL, NULL} /* Sentinel */
@@ -1316,7 +1334,7 @@ static PyObject *
13161334
coro_wrapper_close(PyObject *self, PyObject *args)
13171335
{
13181336
PyCoroWrapper *cw = _PyCoroWrapper_CAST(self);
1319-
return gen_close((PyObject *)cw->cw_coroutine, args);
1337+
return gen_close((PyGenObject *)cw->cw_coroutine, args);
13201338
}
13211339

13221340
static int

0 commit comments

Comments
 (0)