summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorAntoine Pitrou <pitrou@free.fr>2017-09-07 16:56:24 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2017-09-07 16:56:24 (GMT)
commita6a4dc816d68df04a7d592e0b6af8c7ecc4d4344 (patch)
tree1c31738009bee903417cea928e705a112aea2392 /Python
parent1f06a680de465be0c24a78ea3b610053955daa99 (diff)
downloadcpython-a6a4dc816d68df04a7d592e0b6af8c7ecc4d4344.zip
cpython-a6a4dc816d68df04a7d592e0b6af8c7ecc4d4344.tar.gz
cpython-a6a4dc816d68df04a7d592e0b6af8c7ecc4d4344.tar.bz2
bpo-31370: Remove support for threads-less builds (#3385)
* Remove Setup.config * Always define WITH_THREAD for compatibility.
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c124
-rw-r--r--Python/fileutils.c14
-rw-r--r--Python/import.c14
-rw-r--r--Python/mystrtoul.c2
-rw-r--r--Python/pylifecycle.c12
-rw-r--r--Python/pystate.c30
-rw-r--r--Python/sysmodule.c7
-rw-r--r--Python/traceback.c16
8 files changed, 3 insertions, 216 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 436e5ca..8fc65cd 100644
--- a/Python/ceval.c
+++ b/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;
diff --git a/Python/fileutils.c b/Python/fileutils.c
index 97505e5..1cd8ac5 100644
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -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
diff --git a/Python/import.c b/Python/import.c
index 542a91b..a406db3 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -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 */
diff --git a/Python/mystrtoul.c b/Python/mystrtoul.c
index a85790e..7ab5814 100644
--- a/Python/mystrtoul.c
+++ b/Python/mystrtoul.c
@@ -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
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 662405b..7798dfe 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -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
diff --git a/Python/pystate.c b/Python/pystate.c
index 30a3722..379e5a3 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -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
-
-
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 852babb..fba7220 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -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) {
diff --git a/Python/traceback.c b/Python/traceback.c
index b52385e..cd30d56 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -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 */