gh-120321: Make gen.gi_frame.clear() thread-safe (gh-143112) · python/cpython@e2f15ae

GitHub

@@ -91,8 +91,8 @@ gen_traverse(PyObject *self, visitproc visit, void *arg)

9191return0;

9292}

939394-void

95-_PyGen_Finalize(PyObject*self)

94+staticvoid

95+gen_finalize(PyObject*self)

9696{

9797PyGenObject*gen= (PyGenObject*)self;

9898@@ -160,6 +160,34 @@ gen_clear_frame(PyGenObject *gen)

160160_PyErr_ClearExcState(&gen->gi_exc_state);

161161}

162162163+int

164+_PyGen_ClearFrame(PyGenObject*gen)

165+{

166+int8_tframe_state=FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state);

167+do {

168+if (FRAME_STATE_FINISHED(frame_state)) {

169+return0;

170+ }

171+elseif (frame_state==FRAME_EXECUTING) {

172+PyErr_SetString(PyExc_RuntimeError,

173+"cannot clear an executing frame");

174+return-1;

175+ }

176+elseif (FRAME_STATE_SUSPENDED(frame_state)) {

177+PyErr_SetString(PyExc_RuntimeError,

178+"cannot clear an suspended frame");

179+return-1;

180+ }

181+assert(frame_state==FRAME_CREATED);

182+ } while (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_CLEARED));

183+184+if (_PyGen_GetCode(gen)->co_flags&CO_COROUTINE) {

185+_PyErr_WarnUnawaitedCoroutine((PyObject*)gen);

186+ }

187+gen_clear_frame(gen);

188+return0;

189+}

190+163191staticvoid

164192gen_dealloc(PyObject*self)

165193{

@@ -1006,7 +1034,7 @@ PyTypeObject PyGen_Type = {

100610340, /* tp_weaklist */

100710350, /* tp_del */

100810360, /* tp_version_tag */

1009-_PyGen_Finalize,/* tp_finalize */

1037+gen_finalize, /* tp_finalize */

10101038};

1011103910121040staticPyObject*

@@ -1336,7 +1364,7 @@ PyTypeObject PyCoro_Type = {

133613640, /* tp_weaklist */

133713650, /* tp_del */

133813660, /* tp_version_tag */

1339-_PyGen_Finalize,/* tp_finalize */

1367+gen_finalize, /* tp_finalize */

13401368};

1341136913421370staticvoid

@@ -1762,7 +1790,7 @@ PyTypeObject PyAsyncGen_Type = {

176217900, /* tp_weaklist */

176317910, /* tp_del */

176417920, /* tp_version_tag */

1765-_PyGen_Finalize,/* tp_finalize */

1793+gen_finalize, /* tp_finalize */

17661794};

1767179517681796