8000 Merge branch main into main-slp · stackless-dev/stackless@eab1146 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit eab1146

Browse files
author
Anselm Kruis
committed
Merge branch main into main-slp
2 parents 2612eed + 6a150bc commit eab1146

File tree

10 files changed

+320
-186
lines changed

10 files changed

+320
-186
lines changed

Include/internal/pycore_ceval.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,22 @@ extern "C" {
1212
#include "pycore_pystate.h"
1313
#include "pythread.h"
1414

15-
PyAPI_FUNC(void) _Py_FinishPendingCalls(_PyRuntimeState *runtime);
1615
PyAPI_FUNC(void) _PyEval_Initialize(struct _ceval_runtime_state *);
1716
PyAPI_FUNC(void) _PyEval_FiniThreads(
18-
struct _ceval_runtime_state *ceval);
17+
struct _ceval_runtime_state *);
1918
PyAPI_FUNC(void) _PyEval_SignalReceived(
20-
struct _ceval_runtime_state *ceval);
19+
struct _ceval_runtime_state *);
2120
PyAPI_FUNC(int) _PyEval_AddPendingCall(
2221
PyThreadState *tstate,
23-
struct _ceval_runtime_state *ceval,
22+
struct _ceval_runtime_state *,
23+
struct _ceval_interpreter_state *,
24+
unsigned long thread_id,
2425
int (*func)(void *),
2526
void *arg);
27+
PyAPI_FUNC(void) _PyEval_FinishPendingCalls(PyInterpreterState *);
2628
PyAPI_FUNC(void) _PyEval_SignalAsyncExc(
27-
struct _ceval_runtime_state *ceval);
29+
struct _ceval_runtime_state *,
30+
struct _ceval_interpreter_state *);
2831
PyAPI_FUNC(void) _PyEval_ReInitThreads(
2932
_PyRuntimeState *runtime);
3033

Include/internal/pycore_pystate.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct pyruntimestate;
2929

3030
/* ceval state */
3131

32-
struct _pending_calls {
32+
struct _ceval_pending_calls {
3333
int finishing;
3434
PyThread_type_lock lock;
3535
/* Request for running pending calls. */
@@ -40,6 +40,7 @@ struct _pending_calls {
4040
int async_exc;
4141
#define NPENDINGCALLS 32
4242
struct {
43+
unsigned long thread_id;
4344
int (*func)(void *);
4445
void *arg;
4546
} calls[NPENDINGCALLS];
@@ -57,15 +58,21 @@ struct _ceval_runtime_state {
5758
int tracing_possible;
5859
/* This single variable consolidates all requests to break out of
5960
the fast path in the eval loop. */
61+
// XXX This can move to _ceval_interpreter_state once all parts
62+
// from COMPUTE_EVAL_BREAKER have moved under PyInterpreterState.
6063
_Py_atomic_int eval_breaker;
6164
/* Request for dropping the GIL */
6265
_Py_atomic_int gil_drop_request;
63-
struct _pending_calls pending;
6466
/* Request for checking signals. */
6567
_Py_atomic_int signals_pending;
6668
struct _gil_runtime_state gil;
6769
};
6870

71+
struct _ceval_interpreter_state {
72+
struct _ceval_pending_calls pending;
73+
};
74+
75+
6976
/* interpreter state */
7077

7178
typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
@@ -140,6 +147,7 @@ struct _is {
140147

141148
uint64_t tstate_next_unique_id;
142149

150+
struct _ceval_interpreter_state ceval;
143151
struct _warnings_runtime_state warnings;
144152

145153
PyObject *audit_hooks;

Lib/test/test_capi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ def pendingcalls_wait(self, l, n, context = None):
431431
def test_pendingcalls_threaded(self):
432432

433433
#do every callback on a separate thread
434-
n = 32 #total callbacks
434+
n = 32 #total callbacks (see NPENDINGCALLS in pycore_ceval.h)
435435
threads = []
436436
class foo(object):pass
437437
context = foo()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
We added a new internal _Py_AddPendingCall() that operates relative to the
2+
provided interpreter. This allows us to use the existing implementation to
3+
ask another interpreter to do work that cannot be done in the current
4+
interpreter, like decref an object the other interpreter owns. The existing
5+
Py_AddPendingCall() only operates relative to the main interpreter.

Modules/_testcapimodule.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2677,6 +2677,7 @@ pending_threadfunc(PyObject *self, PyObject *arg)
26772677
Py_INCREF(callable);
26782678

26792679
Py_BEGIN_ALLOW_THREADS
2680+
/* XXX Use the internal _Py_AddPendingCall(). */
26802681
r = Py_AddPendingCall(&_pending_callback, callable);
26812682
Py_END_ALLOW_THREADS
26822683

Modules/signalmodule.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <process.h>
2222
#endif
2323
#endif
24+
#include "internal/pycore_pystate.h"
2425

2526
#ifdef HAVE_SIGNAL_H
2627
#include <signal.h>
@@ -259,6 +260,7 @@ trip_signal(int sig_num)
259260
/* Notify ceval.c */
260261
_PyRuntimeState *runtime = &_PyRuntime;
261262
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
263+
PyInterpreterState *interp = runtime->interpreters.main;
262264
_PyEval_SignalReceived(&runtime->ceval);
263265

264266
/* And then write to the wakeup fd *after* setting all the globals and
@@ -299,7 +301,10 @@ trip_signal(int sig_num)
299301
{
300302
/* Py_AddPendingCall() isn't signal-safe, but we
301303
still use it for this exceptional case. */
302-
_PyEval_AddPendingCall(tstate, &runtime->ceval,
304+
_PyEval_AddPendingCall(tstate,
305+
&runtime->ceval,
306+
&interp->ceval,
307+
runtime->main_thread,
303308
report_wakeup_send_error,
304309
(void *)(intptr_t) last_error);
305310
}
@@ -318,7 +323,10 @@ trip_signal(int sig_num)
318323
{
319324
/* Py_AddPendingCall() isn't signal-safe, but we
320325
still use it for this exceptional case. */
321-
_PyEval_AddPendingCall(tstate, &runtime->ceval,
326+
_PyEval_AddPendingCall(tstate,
327+
&runtime->ceval,
328+
&interp->ceval,
329+
runtime->main_thread,
322330
report_wakeup_write_error,
323331
(void *)(intptr_t)errno);
324332
}

0 commit comments

Comments
 (0)
0