Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit757b402

Browse files
gh-104812: Run Pending Calls in any Thread (gh-104813)
For a while now, pending calls only run in the main thread (in the main interpreter). This PR changes things to allow any thread run a pending call, unless the pending call was explicitly added for the main thread to run.
1 parent4e80082 commit757b402

File tree

16 files changed

+761
-118
lines changed

16 files changed

+761
-118
lines changed

‎Include/cpython/ceval.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _P
2222
PyAPI_FUNC(void)_PyEval_SetSwitchInterval(unsigned longmicroseconds);
2323
PyAPI_FUNC(unsigned long)_PyEval_GetSwitchInterval(void);
2424

25+
PyAPI_FUNC(int)_PyEval_MakePendingCalls(PyThreadState*);
26+
2527
PyAPI_FUNC(Py_ssize_t)PyUnstable_Eval_RequestCodeExtraIndex(freefunc);
2628
// Old name -- remove when this API changes:
2729
_Py_DEPRECATED_EXTERNALLY(3.12)staticinlinePy_ssize_t

‎Include/internal/pycore_ceval.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ PyAPI_FUNC(void) _PyEval_SignalReceived(PyInterpreterState *interp);
2727
PyAPI_FUNC(int)_PyEval_AddPendingCall(
2828
PyInterpreterState*interp,
2929
int (*func)(void*),
30-
void*arg);
30+
void*arg,
31+
intmainthreadonly);
3132
PyAPI_FUNC(void)_PyEval_SignalAsyncExc(PyInterpreterState*interp);
3233
#ifdefHAVE_FORK
3334
externPyStatus_PyEval_ReInitThreads(PyThreadState*tstate);

‎Include/internal/pycore_ceval_state.h‎

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@ extern "C" {
1313
#include"pycore_gil.h"// struct _gil_runtime_state
1414

1515

16+
struct_pending_calls {
17+
intbusy;
18+
PyThread_type_locklock;
19+
/* Request for running pending calls. */
20+
_Py_atomic_intcalls_to_do;
21+
/* Request for looking at the `async_exc` field of the current
22+
thread state.
23+
Guarded by the GIL. */
24+
intasync_exc;
25+
#defineNPENDINGCALLS 32
26+
struct_pending_call {
27+
int (*func)(void*);
28+
void*arg;
29+
}calls[NPENDINGCALLS];
30+
intfirst;
31+
intlast;
32+
};
33+
1634
typedefenum {
1735
PERF_STATUS_FAILED=-1,// Perf trampoline is in an invalid state
1836
PERF_STATUS_NO_INIT=0,// Perf trampoline is not initialized
@@ -49,6 +67,8 @@ struct _ceval_runtime_state {
4967
the main thread of the main interpreter can handle signals: see
5068
_Py_ThreadCanHandleSignals(). */
5169
_Py_atomic_intsignals_pending;
70+
/* Pending calls to be made only on the main thread. */
71+
struct_pending_callspending_mainthread;
5272
};
5373

5474
#ifdefPY_HAVE_PERF_TRAMPOLINE
@@ -62,24 +82,6 @@ struct _ceval_runtime_state {
6282
#endif
6383

6484

65-
struct_pending_calls {
66-
intbusy;
67-
PyThread_type_locklock;
68-
/* Request for running pending calls. */
69-
_Py_atomic_intcalls_to_do;
70-
/* Request for looking at the `async_exc` field of the current
71-
thread state.
72-
Guarded by the GIL. */
73-
intasync_exc;
74-
#defineNPENDINGCALLS 32
75-
struct {
76-
int (*func)(void*);
77-
void*arg;
78-
}calls[NPENDINGCALLS];
79-
intfirst;
80-
intlast;
81-
};
82-
8385
struct_ceval_state {
8486
/* This single variable consolidates all requests to break out of
8587
the fast path in the eval loop. */

‎Include/internal/pycore_pystate.h‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,6 @@ _Py_ThreadCanHandleSignals(PyInterpreterState *interp)
6060
}
6161

6262

63-
/* Only execute pending calls on the main thread. */
64-
staticinlineint
65-
_Py_ThreadCanHandlePendingCalls(void)
66-
{
67-
return_Py_IsMainThread();
68-
}
69-
70-
7163
/* Variable and static inline functions for in-line access to current thread
7264
and interpreter state */
7365

‎Lib/test/support/threading_helper.py‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ def join_thread(thread, timeout=None):
115115

116116
@contextlib.contextmanager
117117
defstart_threads(threads,unlock=None):
118-
importfaulthandler
118+
try:
119+
importfaulthandler
120+
exceptImportError:
121+
# It isn't supported on subinterpreters yet.
122+
faulthandler=None
119123
threads=list(threads)
120124
started= []
121125
try:
@@ -147,7 +151,8 @@ def start_threads(threads, unlock=None):
147151
finally:
148152
started= [tfortinstartedift.is_alive()]
149153
ifstarted:
150-
faulthandler.dump_traceback(sys.stdout)
154+
iffaulthandlerisnotNone:
155+
faulthandler.dump_traceback(sys.stdout)
151156
raiseAssertionError('Unable to join %d threads'%len(started))
152157

153158

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp