Skip to content

Commit d7c99b0

Browse files
gh-140266: Fix data race when accessing func_code in PyFunctionObject
1 parent 0eaf260 commit d7c99b0

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

Objects/funcobject.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,8 @@ func_get_code(PyObject *self, void *Py_UNUSED(ignored))
631631
return NULL;
632632
}
633633

634-
return Py_NewRef(op->func_code);
634+
PyCodeObject *code = _Py_atomic_load_ptr(&op->func_code);
635+
return Py_NewRef(code);
635636
}
636637

637638
static int
@@ -664,7 +665,7 @@ func_set_code(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
664665
return -1;
665666
}
666667

667-
PyObject *func_code = PyFunction_GET_CODE(op);
668+
PyCodeObject *func_code = _Py_atomic_load_ptr(&op->func_code);
668669
int old_flags = ((PyCodeObject *)func_code)->co_flags;
669670
int new_flags = ((PyCodeObject *)value)->co_flags;
670671
int mask = CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR;
@@ -679,7 +680,10 @@ func_set_code(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
679680

680681
handle_func_event(PyFunction_EVENT_MODIFY_CODE, op, value);
681682
_PyFunction_ClearVersion(op);
682-
Py_XSETREF(op->func_code, Py_NewRef(value));
683+
PyCodeObject *new = (PyCodeObject *)Py_NewRef(value);
684+
PyCodeObject *old =
685+
(PyCodeObject *)_Py_atomic_exchange_ptr(&op->func_code, new);
686+
Py_XDECREF(old);
683687
return 0;
684688
}
685689

0 commit comments

Comments
 (0)