mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-31370: Remove support for threads-less builds (#3385)
* Remove Setup.config * Always define WITH_THREAD for compatibility.
This commit is contained in:
parent
1f06a680de
commit
a6a4dc816d
135 changed files with 2472 additions and 4377 deletions
124
Python/ceval.c
124
Python/ceval.c
|
@ -87,11 +87,7 @@ static long dxp[256];
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
#define GIL_REQUEST _Py_atomic_load_relaxed(&gil_drop_request)
|
||||
#else
|
||||
#define GIL_REQUEST 0
|
||||
#endif
|
||||
|
||||
/* This can set eval_breaker to 0 even though gil_drop_request became
|
||||
1. We believe this is all right because the eval loop will release
|
||||
|
@ -103,8 +99,6 @@ static long dxp[256];
|
|||
_Py_atomic_load_relaxed(&pendingcalls_to_do) | \
|
||||
pending_async_exc)
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
|
||||
#define SET_GIL_DROP_REQUEST() \
|
||||
do { \
|
||||
_Py_atomic_store_relaxed(&gil_drop_request, 1); \
|
||||
|
@ -117,8 +111,6 @@ static long dxp[256];
|
|||
COMPUTE_EVAL_BREAKER(); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
/* Pending calls are only modified under pending_lock */
|
||||
#define SIGNAL_PENDING_CALLS() \
|
||||
do { \
|
||||
|
@ -151,8 +143,6 @@ static _Py_atomic_int pendingcalls_to_do = {0};
|
|||
Guarded by the GIL. */
|
||||
static int pending_async_exc = 0;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
@ -256,8 +246,6 @@ PyEval_ReInitThreads(void)
|
|||
_PyThreadState_DeleteExcept(current_tstate);
|
||||
}
|
||||
|
||||
#endif /* WITH_THREAD */
|
||||
|
||||
/* This function is used to signal that async exceptions are waiting to be
|
||||
raised, therefore it is also useful in non-threaded builds. */
|
||||
|
||||
|
@ -277,10 +265,8 @@ PyEval_SaveThread(void)
|
|||
PyThreadState *tstate = PyThreadState_Swap(NULL);
|
||||
if (tstate == NULL)
|
||||
Py_FatalError("PyEval_SaveThread: NULL tstate");
|
||||
#ifdef WITH_THREAD
|
||||
if (gil_created())
|
||||
drop_gil(tstate);
|
||||
#endif
|
||||
return tstate;
|
||||
}
|
||||
|
||||
|
@ -289,7 +275,6 @@ PyEval_RestoreThread(PyThreadState *tstate)
|
|||
{
|
||||
if (tstate == NULL)
|
||||
Py_FatalError("PyEval_RestoreThread: NULL tstate");
|
||||
#ifdef WITH_THREAD
|
||||
if (gil_created()) {
|
||||
int err = errno;
|
||||
take_gil(tstate);
|
||||
|
@ -301,7 +286,6 @@ PyEval_RestoreThread(PyThreadState *tstate)
|
|||
}
|
||||
errno = err;
|
||||
}
|
||||
#endif
|
||||
PyThreadState_Swap(tstate);
|
||||
}
|
||||
|
||||
|
@ -320,14 +304,12 @@ PyEval_RestoreThread(PyThreadState *tstate)
|
|||
Note that because registry may occur from within signal handlers,
|
||||
or other asynchronous events, calling malloc() is unsafe!
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
Any thread can schedule pending calls, but only the main thread
|
||||
will execute them.
|
||||
There is no facility to schedule calls to a particular thread, but
|
||||
that should be easy to change, should that ever be required. In
|
||||
that case, the static variables here should go into the python
|
||||
threadstate.
|
||||
#endif
|
||||
*/
|
||||
|
||||
void
|
||||
|
@ -339,9 +321,7 @@ _PyEval_SignalReceived(void)
|
|||
SIGNAL_PENDING_CALLS();
|
||||
}
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
|
||||
/* The WITH_THREAD implementation is thread-safe. It allows
|
||||
/* This implementation is thread-safe. It allows
|
||||
scheduling to be made from any thread, and even from an executing
|
||||
callback.
|
||||
*/
|
||||
|
@ -464,106 +444,6 @@ error:
|
|||
return -1;
|
||||
}
|
||||
|
||||
#else /* if ! defined WITH_THREAD */
|
||||
|
||||
/*
|
||||
WARNING! ASYNCHRONOUSLY EXECUTING CODE!
|
||||
This code is used for signal handling in python that isn't built
|
||||
with WITH_THREAD.
|
||||
Don't use this implementation when Py_AddPendingCalls() can happen
|
||||
on a different thread!
|
||||
|
||||
There are two possible race conditions:
|
||||
(1) nested asynchronous calls to Py_AddPendingCall()
|
||||
(2) AddPendingCall() calls made while pending calls are being processed.
|
||||
|
||||
(1) is very unlikely because typically signal delivery
|
||||
is blocked during signal handling. So it should be impossible.
|
||||
(2) is a real possibility.
|
||||
The current code is safe against (2), but not against (1).
|
||||
The safety against (2) is derived from the fact that only one
|
||||
thread is present, interrupted by signals, and that the critical
|
||||
section is protected with the "busy" variable. On Windows, which
|
||||
delivers SIGINT on a system thread, this does not hold and therefore
|
||||
Windows really shouldn't use this version.
|
||||
The two threads could theoretically wiggle around the "busy" variable.
|
||||
*/
|
||||
|
||||
#define NPENDINGCALLS 32
|
||||
static struct {
|
||||
int (*func)(void *);
|
||||
void *arg;
|
||||
} pendingcalls[NPENDINGCALLS];
|
||||
static volatile int pendingfirst = 0;
|
||||
static volatile int pendinglast = 0;
|
||||
|
||||
int
|
||||
Py_AddPendingCall(int (*func)(void *), void *arg)
|
||||
{
|
||||
static volatile int busy = 0;
|
||||
int i, j;
|
||||
/* XXX Begin critical section */
|
||||
if (busy)
|
||||
return -1;
|
||||
busy = 1;
|
||||
i = pendinglast;
|
||||
j = (i + 1) % NPENDINGCALLS;
|
||||
if (j == pendingfirst) {
|
||||
busy = 0;
|
||||
return -1; /* Queue full */
|
||||
}
|
||||
pendingcalls[i].func = func;
|
||||
pendingcalls[i].arg = arg;
|
||||
pendinglast = j;
|
||||
|
||||
SIGNAL_PENDING_CALLS();
|
||||
busy = 0;
|
||||
/* XXX End critical section */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Py_MakePendingCalls(void)
|
||||
{
|
||||
static int busy = 0;
|
||||
if (busy)
|
||||
return 0;
|
||||
busy = 1;
|
||||
|
||||
/* unsignal before starting to call callbacks, so that any callback
|
||||
added in-between re-signals */
|
||||
UNSIGNAL_PENDING_CALLS();
|
||||
/* Python signal handler doesn't really queue a callback: it only signals
|
||||
that a signal was received, see _PyEval_SignalReceived(). */
|
||||
if (PyErr_CheckSignals() < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int i;
|
||||
int (*func)(void *);
|
||||
void *arg;
|
||||
i = pendingfirst;
|
||||
if (i == pendinglast)
|
||||
break; /* Queue empty */
|
||||
func = pendingcalls[i].func;
|
||||
arg = pendingcalls[i].arg;
|
||||
pendingfirst = (i + 1) % NPENDINGCALLS;
|
||||
if (func(arg) < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
busy = 0;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
busy = 0;
|
||||
SIGNAL_PENDING_CALLS(); /* We're not done yet */
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* WITH_THREAD */
|
||||
|
||||
|
||||
/* The interpreter's recursion limit */
|
||||
|
||||
|
@ -1101,7 +981,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
if (Py_MakePendingCalls() < 0)
|
||||
goto error;
|
||||
}
|
||||
#ifdef WITH_THREAD
|
||||
if (_Py_atomic_load_relaxed(&gil_drop_request)) {
|
||||
/* Give another thread a chance */
|
||||
if (PyThreadState_Swap(NULL) != tstate)
|
||||
|
@ -1121,7 +1000,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
if (PyThreadState_Swap(tstate) != NULL)
|
||||
Py_FatalError("ceval: orphan tstate");
|
||||
}
|
||||
#endif
|
||||
/* Check for asynchronous exceptions. */
|
||||
if (tstate->async_exc != NULL) {
|
||||
PyObject *exc = tstate->async_exc;
|
||||
|
|
|
@ -680,9 +680,7 @@ _Py_fstat(int fd, struct _Py_stat_struct *status)
|
|||
{
|
||||
int res;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
assert(PyGILState_Check());
|
||||
#endif
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
res = _Py_fstat_noraise(fd, status);
|
||||
|
@ -999,10 +997,8 @@ _Py_open_impl(const char *pathname, int flags, int gil_held)
|
|||
int
|
||||
_Py_open(const char *pathname, int flags)
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
/* _Py_open() must be called with the GIL held. */
|
||||
assert(PyGILState_Check());
|
||||
#endif
|
||||
return _Py_open_impl(pathname, flags, 1);
|
||||
}
|
||||
|
||||
|
@ -1095,9 +1091,7 @@ _Py_fopen_obj(PyObject *path, const char *mode)
|
|||
wchar_t wmode[10];
|
||||
int usize;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
assert(PyGILState_Check());
|
||||
#endif
|
||||
|
||||
if (!PyUnicode_Check(path)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
|
@ -1125,9 +1119,7 @@ _Py_fopen_obj(PyObject *path, const char *mode)
|
|||
PyObject *bytes;
|
||||
char *path_bytes;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
assert(PyGILState_Check());
|
||||
#endif
|
||||
|
||||
if (!PyUnicode_FSConverter(path, &bytes))
|
||||
return NULL;
|
||||
|
@ -1177,9 +1169,7 @@ _Py_read(int fd, void *buf, size_t count)
|
|||
int err;
|
||||
int async_err = 0;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
assert(PyGILState_Check());
|
||||
#endif
|
||||
|
||||
/* _Py_read() must not be called with an exception set, otherwise the
|
||||
* caller may think that read() was interrupted by a signal and the signal
|
||||
|
@ -1318,9 +1308,7 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held)
|
|||
Py_ssize_t
|
||||
_Py_write(int fd, const void *buf, size_t count)
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
assert(PyGILState_Check());
|
||||
#endif
|
||||
|
||||
/* _Py_write() must not be called with an exception set, otherwise the
|
||||
* caller may think that write() was interrupted by a signal and the signal
|
||||
|
@ -1471,9 +1459,7 @@ _Py_dup(int fd)
|
|||
DWORD ftype;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
assert(PyGILState_Check());
|
||||
#endif
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
_Py_BEGIN_SUPPRESS_IPH
|
||||
|
|
|
@ -142,8 +142,6 @@ _PyImportZip_Init(void)
|
|||
in different threads to return with a partially loaded module.
|
||||
These calls are serialized by the global interpreter lock. */
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
|
||||
#include "pythread.h"
|
||||
|
||||
static PyThread_type_lock import_lock = 0;
|
||||
|
@ -224,8 +222,6 @@ _PyImport_ReInitLock(void)
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*[clinic input]
|
||||
_imp.lock_held
|
||||
|
||||
|
@ -238,11 +234,7 @@ static PyObject *
|
|||
_imp_lock_held_impl(PyObject *module)
|
||||
/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
return PyBool_FromLong(import_lock_thread != PYTHREAD_INVALID_THREAD_ID);
|
||||
#else
|
||||
Py_RETURN_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
|
@ -258,9 +250,7 @@ static PyObject *
|
|||
_imp_acquire_lock_impl(PyObject *module)
|
||||
/*[clinic end generated code: output=1aff58cb0ee1b026 input=4a2d4381866d5fdc]*/
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
_PyImport_AcquireLock();
|
||||
#endif
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
@ -276,13 +266,11 @@ static PyObject *
|
|||
_imp_release_lock_impl(PyObject *module)
|
||||
/*[clinic end generated code: output=7faab6d0be178b0a input=934fb11516dd778b]*/
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
if (_PyImport_ReleaseLock() < 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"not holding the import lock");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
@ -290,12 +278,10 @@ void
|
|||
_PyImport_Fini(void)
|
||||
{
|
||||
Py_CLEAR(extensions);
|
||||
#ifdef WITH_THREAD
|
||||
if (import_lock != NULL) {
|
||||
PyThread_free_lock(import_lock);
|
||||
import_lock = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Helper for sys */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#include "Python.h"
|
||||
|
||||
#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
|
||||
#if defined(__sgi) && !defined(_SGI_MP_SOURCE)
|
||||
#define _SGI_MP_SOURCE
|
||||
#endif
|
||||
|
||||
|
|
|
@ -72,10 +72,8 @@ extern int _PyTraceMalloc_Init(void);
|
|||
extern int _PyTraceMalloc_Fini(void);
|
||||
extern void _Py_ReadyTypes(void);
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *);
|
||||
extern void _PyGILState_Fini(void);
|
||||
#endif /* WITH_THREAD */
|
||||
|
||||
/* Global configuration variable declarations are in pydebug.h */
|
||||
/* XXX (ncoghlan): move those declarations to pylifecycle.h? */
|
||||
|
@ -618,7 +616,6 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
|
|||
Py_FatalError("Py_InitializeCore: can't make first thread");
|
||||
(void) PyThreadState_Swap(tstate);
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
/* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because
|
||||
destroying the GIL might fail when it is being referenced from
|
||||
another running thread (see issue #9901).
|
||||
|
@ -627,7 +624,6 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
|
|||
_PyEval_FiniThreads();
|
||||
/* Auto-thread-state API */
|
||||
_PyGILState_Init(interp, tstate);
|
||||
#endif /* WITH_THREAD */
|
||||
|
||||
_Py_ReadyTypes();
|
||||
|
||||
|
@ -1084,9 +1080,7 @@ Py_FinalizeEx(void)
|
|||
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
|
||||
|
||||
/* Cleanup auto-thread-state */
|
||||
#ifdef WITH_THREAD
|
||||
_PyGILState_Fini();
|
||||
#endif /* WITH_THREAD */
|
||||
|
||||
/* Delete current thread. After this, many C API calls become crashy. */
|
||||
PyThreadState_Swap(NULL);
|
||||
|
@ -1142,11 +1136,9 @@ Py_NewInterpreter(void)
|
|||
if (!_Py_Initialized)
|
||||
Py_FatalError("Py_NewInterpreter: call Py_Initialize first");
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
/* Issue #10915, #15751: The GIL API doesn't work with multiple
|
||||
interpreters: disable PyGILState_Check(). */
|
||||
_PyGILState_check_enabled = 0;
|
||||
#endif
|
||||
|
||||
interp = PyInterpreterState_New();
|
||||
if (interp == NULL)
|
||||
|
@ -1850,9 +1842,7 @@ exit:
|
|||
|
||||
/* Clean up and exit */
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
# include "pythread.h"
|
||||
#endif
|
||||
|
||||
static void (*pyexitfunc)(void) = NULL;
|
||||
/* For the atexit module. */
|
||||
|
@ -1878,7 +1868,6 @@ call_py_exitfuncs(void)
|
|||
static void
|
||||
wait_for_thread_shutdown(void)
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
_Py_IDENTIFIER(_shutdown);
|
||||
PyObject *result;
|
||||
PyObject *threading = _PyImport_GetModuleId(&PyId_threading);
|
||||
|
@ -1896,7 +1885,6 @@ wait_for_thread_shutdown(void)
|
|||
Py_DECREF(result);
|
||||
}
|
||||
Py_DECREF(threading);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define NEXITFUNCS 32
|
||||
|
|
|
@ -36,7 +36,6 @@ extern "C" {
|
|||
|
||||
int _PyGILState_check_enabled = 1;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
#include "pythread.h"
|
||||
static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
|
||||
#define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock()))
|
||||
|
@ -49,11 +48,6 @@ static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
|
|||
/* TODO: Given interp_main, it may be possible to kill this ref */
|
||||
static PyInterpreterState *autoInterpreterState = NULL;
|
||||
static int autoTLSkey = -1;
|
||||
#else
|
||||
#define HEAD_INIT() /* Nothing */
|
||||
#define HEAD_LOCK() /* Nothing */
|
||||
#define HEAD_UNLOCK() /* Nothing */
|
||||
#endif
|
||||
|
||||
static PyInterpreterState *interp_head = NULL;
|
||||
static PyInterpreterState *interp_main = NULL;
|
||||
|
@ -63,9 +57,7 @@ static PyInterpreterState *interp_main = NULL;
|
|||
_Py_atomic_address _PyThreadState_Current = {0};
|
||||
PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
static void _PyGILState_NoteThreadState(PyThreadState* tstate);
|
||||
#endif
|
||||
|
||||
/* _next_interp_id is an auto-numbered sequence of small integers.
|
||||
It gets initialized in _PyInterpreterState_Init(), which is called
|
||||
|
@ -93,10 +85,8 @@ PyInterpreterState_New(void)
|
|||
|
||||
if (interp != NULL) {
|
||||
HEAD_INIT();
|
||||
#ifdef WITH_THREAD
|
||||
if (head_mutex == NULL)
|
||||
Py_FatalError("Can't initialize threads for interpreter");
|
||||
#endif
|
||||
interp->modules_by_index = NULL;
|
||||
interp->sysdict = NULL;
|
||||
interp->builtins = NULL;
|
||||
|
@ -206,12 +196,10 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
|
|||
}
|
||||
HEAD_UNLOCK();
|
||||
PyMem_RawFree(interp);
|
||||
#ifdef WITH_THREAD
|
||||
if (interp_head == NULL && head_mutex != NULL) {
|
||||
PyThread_free_lock(head_mutex);
|
||||
head_mutex = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -252,11 +240,7 @@ new_threadstate(PyInterpreterState *interp, int init)
|
|||
tstate->use_tracing = 0;
|
||||
tstate->gilstate_counter = 0;
|
||||
tstate->async_exc = NULL;
|
||||
#ifdef WITH_THREAD
|
||||
tstate->thread_id = PyThread_get_thread_ident();
|
||||
#else
|
||||
tstate->thread_id = 0;
|
||||
#endif
|
||||
|
||||
tstate->dict = NULL;
|
||||
|
||||
|
@ -314,9 +298,7 @@ _PyThreadState_Prealloc(PyInterpreterState *interp)
|
|||
void
|
||||
_PyThreadState_Init(PyThreadState *tstate)
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
_PyGILState_NoteThreadState(tstate);
|
||||
#endif
|
||||
}
|
||||
|
||||
PyObject*
|
||||
|
@ -498,15 +480,12 @@ PyThreadState_Delete(PyThreadState *tstate)
|
|||
{
|
||||
if (tstate == GET_TSTATE())
|
||||
Py_FatalError("PyThreadState_Delete: tstate is still current");
|
||||
#ifdef WITH_THREAD
|
||||
if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
|
||||
PyThread_delete_key_value(autoTLSkey);
|
||||
#endif /* WITH_THREAD */
|
||||
tstate_delete_common(tstate);
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
void
|
||||
PyThreadState_DeleteCurrent()
|
||||
{
|
||||
|
@ -520,7 +499,6 @@ PyThreadState_DeleteCurrent()
|
|||
SET_TSTATE(NULL);
|
||||
PyEval_ReleaseLock();
|
||||
}
|
||||
#endif /* WITH_THREAD */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -588,7 +566,7 @@ PyThreadState_Swap(PyThreadState *newts)
|
|||
to be used for a thread. Check this the best we can in debug
|
||||
builds.
|
||||
*/
|
||||
#if defined(Py_DEBUG) && defined(WITH_THREAD)
|
||||
#if defined(Py_DEBUG)
|
||||
if (newts) {
|
||||
/* This can be called from PyEval_RestoreThread(). Similar
|
||||
to it, we need to ensure errno doesn't change.
|
||||
|
@ -749,7 +727,6 @@ _PyThread_CurrentFrames(void)
|
|||
}
|
||||
|
||||
/* Python "auto thread state" API. */
|
||||
#ifdef WITH_THREAD
|
||||
|
||||
/* Keep this as a static, as it is not reliable! It can only
|
||||
ever be compared to the state for the *current* thread.
|
||||
|
@ -805,10 +782,8 @@ _PyGILState_Fini(void)
|
|||
void
|
||||
_PyGILState_Reinit(void)
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
head_mutex = NULL;
|
||||
HEAD_INIT();
|
||||
#endif
|
||||
PyThreadState *tstate = PyGILState_GetThisThreadState();
|
||||
PyThread_delete_key(autoTLSkey);
|
||||
if ((autoTLSkey = PyThread_create_key()) == -1)
|
||||
|
@ -960,10 +935,7 @@ PyGILState_Release(PyGILState_STATE oldstate)
|
|||
PyEval_SaveThread();
|
||||
}
|
||||
|
||||
#endif /* WITH_THREAD */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -556,7 +556,6 @@ PyDoc_STRVAR(getcheckinterval_doc,
|
|||
"getcheckinterval() -> current check interval; see setcheckinterval()."
|
||||
);
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
static PyObject *
|
||||
sys_setswitchinterval(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
@ -594,8 +593,6 @@ PyDoc_STRVAR(getswitchinterval_doc,
|
|||
"getswitchinterval() -> current thread switch interval; see setswitchinterval()."
|
||||
);
|
||||
|
||||
#endif /* WITH_THREAD */
|
||||
|
||||
static PyObject *
|
||||
sys_setrecursionlimit(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
@ -1418,12 +1415,10 @@ static PyMethodDef sys_methods[] = {
|
|||
setcheckinterval_doc},
|
||||
{"getcheckinterval", sys_getcheckinterval, METH_NOARGS,
|
||||
getcheckinterval_doc},
|
||||
#ifdef WITH_THREAD
|
||||
{"setswitchinterval", sys_setswitchinterval, METH_VARARGS,
|
||||
setswitchinterval_doc},
|
||||
{"getswitchinterval", sys_getswitchinterval, METH_NOARGS,
|
||||
getswitchinterval_doc},
|
||||
#endif
|
||||
#ifdef HAVE_DLOPEN
|
||||
{"setdlopenflags", sys_setdlopenflags, METH_VARARGS,
|
||||
setdlopenflags_doc},
|
||||
|
@ -2055,9 +2050,7 @@ _PySys_BeginInit(void)
|
|||
PyUnicode_FromString("legacy"));
|
||||
#endif
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo());
|
||||
#endif
|
||||
|
||||
/* initialize asyncgen_hooks */
|
||||
if (AsyncGenHooksType.tp_name == NULL) {
|
||||
|
|
|
@ -749,7 +749,6 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
|
|||
PyThreadState *tstate;
|
||||
unsigned int nthreads;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
if (current_tstate == NULL) {
|
||||
/* _Py_DumpTracebackThreads() is called from signal handlers by
|
||||
faulthandler.
|
||||
|
@ -777,21 +776,6 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
|
|||
interp = current_tstate->interp;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (current_tstate == NULL) {
|
||||
/* Call _PyThreadState_UncheckedGet() instead of PyThreadState_Get()
|
||||
to not fail with a fatal error if the thread state is NULL. */
|
||||
current_tstate = _PyThreadState_UncheckedGet();
|
||||
}
|
||||
|
||||
if (interp == NULL) {
|
||||
if (current_tstate == NULL) {
|
||||
/* We need the interpreter state to get Python threads */
|
||||
return "unable to get the interpreter state";
|
||||
}
|
||||
interp = current_tstate->interp;
|
||||
}
|
||||
#endif
|
||||
assert(interp != NULL);
|
||||
|
||||
/* Get the current interpreter from the current thread */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue