Skip to content

Commit daedf41

Browse files
kumaraditya303seehwan80
authored andcommitted
pythongh-131141: fix data race in instrumentation while registering callback (python#131142)
1 parent c1e0419 commit daedf41

File tree

2 files changed

+14
-10
lines changed

2 files changed

+14
-10
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix data race in :data:`sys.monitoring` instrumentation while registering callback.

Python/instrumentation.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3006,13 +3006,6 @@ static PyObject *make_branch_handler(int tool_id, PyObject *handler, bool right)
30063006
return (PyObject *)callback;
30073007
}
30083008

3009-
/* Consumes a reference to obj */
3010-
static PyObject *exchange_callables(int tool_id, int event_id, PyObject *obj)
3011-
{
3012-
PyInterpreterState *is = _PyInterpreterState_GET();
3013-
return _Py_atomic_exchange_ptr(&is->monitoring_callables[tool_id][event_id], obj);
3014-
}
3015-
30163009
PyObject *
30173010
_PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj)
30183011
{
@@ -3036,11 +3029,21 @@ _PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj)
30363029
return NULL;
30373030
}
30383031
}
3039-
Py_XDECREF(exchange_callables(tool_id, PY_MONITORING_EVENT_BRANCH_RIGHT, right));
3040-
res = exchange_callables(tool_id, PY_MONITORING_EVENT_BRANCH_LEFT, left);
3032+
PyInterpreterState *interp = _PyInterpreterState_GET();
3033+
_PyEval_StopTheWorld(interp);
3034+
PyObject *old_right = interp->monitoring_callables[tool_id][PY_MONITORING_EVENT_BRANCH_RIGHT];
3035+
interp->monitoring_callables[tool_id][PY_MONITORING_EVENT_BRANCH_RIGHT] = right;
3036+
res = interp->monitoring_callables[tool_id][PY_MONITORING_EVENT_BRANCH_LEFT];
3037+
interp->monitoring_callables[tool_id][PY_MONITORING_EVENT_BRANCH_LEFT] = left;
3038+
_PyEval_StartTheWorld(interp);
3039+
Py_XDECREF(old_right);
30413040
}
30423041
else {
3043-
res = exchange_callables(tool_id, event_id, Py_XNewRef(obj));
3042+
PyInterpreterState *interp = _PyInterpreterState_GET();
3043+
_PyEval_StopTheWorld(interp);
3044+
res = interp->monitoring_callables[tool_id][event_id];
3045+
interp->monitoring_callables[tool_id][event_id] = Py_XNewRef(obj);
3046+
_PyEval_StartTheWorld(interp);
30443047
}
30453048
if (res != NULL && Py_TYPE(res) == &_PyLegacyBranchEventHandler_Type) {
30463049
_PyLegacyBranchEventHandler *wrapper = (_PyLegacyBranchEventHandler *)res;

0 commit comments

Comments
 (0)