Skip to content

Commit 8393bfe

Browse files
committed
Don't potentially leak executor
1 parent 597f40d commit 8393bfe

File tree

7 files changed

+37
-14
lines changed

7 files changed

+37
-14
lines changed

Include/cpython/pyatomic_msc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ _Py_atomic_load_uintptr_acquire(const uintptr_t *obj)
922922
#elif defined(_M_ARM64)
923923
return (uintptr_t)__ldar64((unsigned __int64 volatile *)obj);
924924
#else
925-
# error "no implementation of _Py_atomic_load_ptr_acquire"
925+
# error "no implementation of _Py_atomic_load_uintptr_acquire"
926926
#endif
927927
}
928928

@@ -947,7 +947,7 @@ _Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value)
947947
_Py_atomic_ASSERT_ARG_TYPE(unsigned __int64);
948948
__stlr64((unsigned __int64 volatile *)obj, (unsigned __int64)value);
949949
#else
950-
# error "no implementation of _Py_atomic_store_int_release"
950+
# error "no implementation of _Py_atomic_store_uintptr_release"
951951
#endif
952952
}
953953

Include/internal/pycore_pyatomic_ft_wrappers.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ extern "C" {
4040
_Py_atomic_store_ssize_relaxed(&value, new_value)
4141
#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) \
4242
_Py_atomic_store_uint8_relaxed(&value, new_value)
43+
#define FT_ATOMIC_EXCHANGE_PYOBJECT(value, new_value) \
44+
_Py_atomic_exchange_ptr(&value, new_value)
45+
4346
#else
4447
#define FT_ATOMIC_LOAD_PTR(value) value
4548
#define FT_ATOMIC_LOAD_SSIZE(value) value
@@ -52,6 +55,16 @@ extern "C" {
5255
#define FT_ATOMIC_STORE_UINTPTR_RELEASE(value, new_value) value = new_value
5356
#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) value = new_value
5457
#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) value = new_value
58+
#define FT_ATOMIC_EXCHANGE_PYOBJECT(value, new_value) \
59+
_atomic_exchange_pyobject_withgil(&value, new_value)
60+
61+
static inline PyObject *
62+
_atomic_exchange_pyobject_withgil(PyObject **src, PyObject *new_value)
63+
{
64+
PyObject *res = *src;
65+
*src = new_value;
66+
return res;
67+
}
5568

5669
#endif
5770

Python/bytecodes.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2379,6 +2379,14 @@ dummy_func(
23792379
};
23802380

23812381
tier1 inst(ENTER_EXECUTOR, (--)) {
2382+
int prevoparg = oparg;
2383+
CHECK_EVAL_BREAKER();
2384+
if (this_instr->op.code != ENTER_EXECUTOR ||
2385+
this_instr->op.arg != prevoparg) {
2386+
next_instr = this_instr;
2387+
DISPATCH();
2388+
}
2389+
23822390
PyCodeObject *code = _PyFrame_GetCode(frame);
23832391
_PyExecutorObject *executor = code->co_executors->executors[oparg & 255];
23842392
assert(executor->vm_data.index == INSTR_OFFSET() - 1);
@@ -2387,7 +2395,6 @@ dummy_func(
23872395
assert(tstate->previous_executor == NULL);
23882396
tstate->previous_executor = Py_None;
23892397
Py_INCREF(executor);
2390-
CHECK_EVAL_BREAKER();
23912398
GOTO_TIER_TWO(executor);
23922399
}
23932400

Python/generated_cases.c.h

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

Python/instrumentation.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
assert(!_PyInterpreterState_GET()->stoptheworld.world_stopped); \
4343
Py_BEGIN_CRITICAL_SECTION(code)
4444

45-
#define UNLOCK_CODE(code) Py_END_CRITICAL_SECTION()
45+
#define UNLOCK_CODE() Py_END_CRITICAL_SECTION()
4646

4747
#else
4848

@@ -1374,15 +1374,10 @@ _PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj)
13741374
PyInterpreterState *is = _PyInterpreterState_GET();
13751375
assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS);
13761376
assert(0 <= event_id && event_id < _PY_MONITORING_EVENTS);
1377-
#ifdef Py_GIL_DISABLED
1378-
PyObject *callback = _Py_atomic_exchange_ptr(
1379-
&is->monitoring_callables[tool_id][event_id],
1377+
PyObject *callback = FT_ATOMIC_EXCHANGE_PYOBJECT(is->monitoring_callables[tool_id][event_id],
13801378
Py_XNewRef(obj)
13811379
);
1382-
#else
1383-
PyObject *callback = is->monitoring_callables[tool_id][event_id];
1384-
is->monitoring_callables[tool_id][event_id] = Py_XNewRef(obj);
1385-
#endif
1380+
13861381
return callback;
13871382
}
13881383

Python/legacy_tracing.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
586586
// needs to be decref'd outside of the lock
587587
PyObject *old_traceobj;
588588
LOCK_SETUP();
589-
int tracing_threads = setup_tracing(tstate, func, arg, &old_traceobj);
589+
Py_ssize_t tracing_threads = setup_tracing(tstate, func, arg, &old_traceobj);
590590
UNLOCK_SETUP();
591591
Py_XDECREF(old_traceobj);
592592
if (tracing_threads < 0) {

Tools/jit/template.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "pycore_opcode_metadata.h"
1313
#include "pycore_opcode_utils.h"
1414
#include "pycore_optimizer.h"
15+
#include "pycore_pyatomic_ft_wrappers.h"
1516
#include "pycore_range.h"
1617
#include "pycore_setobject.h"
1718
#include "pycore_sliceobject.h"

0 commit comments

Comments
 (0)