// See also PyInterpreterState_Get() and _PyInterpreterState_GET().
extern PyInterpreterState* _PyGILState_GetInterpreterStateUnsafe(void);
+#ifndef NDEBUG
+/* Modern equivalent of assert(PyGILState_Check()) */
+static inline void
+_Py_AssertHoldsTstateFunc(const char *func)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ _Py_EnsureFuncTstateNotNULL(func, tstate);
+}
+#define _Py_AssertHoldsTstate() _Py_AssertHoldsTstateFunc(__func__)
+#else
+#define _Py_AssertHoldsTstate()
+#endif
+
#ifdef __cplusplus
}
#endif
#include "pycore_fileutils.h" // _Py_set_inheritable()
#include "pycore_moduleobject.h" // _PyModule_GetState
#include "pycore_time.h" // _PyTime_AsMilliseconds()
+#include "pycore_pystate.h" // _Py_AssertHoldsTstate()
#include "pycore_pyatomic_ft_wrappers.h"
#ifdef _Py_MEMORY_SANITIZER
struct timeval tv, *tvp;
#endif
- /* must be called with the GIL held */
- assert(PyGILState_Check());
+ /* must be called with a thread state */
+ _Py_AssertHoldsTstate();
/* Error condition is for output only */
assert(!(connect && !writing));
int deadline_initialized = 0;
int res;
- /* sock_call() must be called with the GIL held. */
- assert(PyGILState_Check());
+ /* sock_call() must be called with a thread state. */
+ _Py_AssertHoldsTstate();
/* outer loop to retry select() when select() is interrupted by a signal
or to retry select()+sock_func() on false positive (see above) */
}
int PyRefTracer_SetTracer(PyRefTracer tracer, void *data) {
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
_PyRuntime.ref_tracer.tracer_func = tracer;
_PyRuntime.ref_tracer.tracer_data = data;
return 0;
}
PyRefTracer PyRefTracer_GetTracer(void** data) {
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
if (data != NULL) {
*data = _PyRuntime.ref_tracer.tracer_data;
}
static inline void
_PyMem_DebugCheckGIL(const char *func)
{
- if (!PyGILState_Check()) {
+ PyThreadState *tstate = _PyThreadState_GET();
+ if (tstate == NULL) {
#ifndef Py_GIL_DISABLED
_Py_FatalErrorFunc(func,
"Python memory allocator called "
void
_Py_FinishPendingCalls(PyThreadState *tstate)
{
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
assert(_PyThreadState_CheckConsistency(tstate));
struct _pending_calls *pending = &tstate->interp->ceval.pending;
int
Py_MakePendingCalls(void)
{
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
PyThreadState *tstate = _PyThreadState_GET();
assert(_PyThreadState_CheckConsistency(tstate));
PyObject* _Py_HOT_FUNCTION
PyErr_Occurred(void)
{
- /* The caller must hold the GIL. */
- assert(PyGILState_Check());
+ /* The caller must hold a thread state. */
+ _Py_AssertHoldsTstate();
PyThreadState *tstate = _PyThreadState_GET();
return _PyErr_Occurred(tstate);
#include "Python.h"
#include "pycore_fileutils.h" // fileutils definitions
#include "pycore_runtime.h" // _PyRuntime
+#include "pycore_pystate.h" // _Py_AssertHoldsTstate()
#include "osdefs.h" // SEP
#include <stdlib.h> // mbstowcs()
{
int res;
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
Py_BEGIN_ALLOW_THREADS
res = _Py_fstat_noraise(fd, status);
_Py_open(const char *pathname, int flags)
{
/* _Py_open() must be called with the GIL held. */
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
return _Py_open_impl(pathname, flags, 1);
}
FILE*
Py_fopen(PyObject *path, const char *mode)
{
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
if (PySys_Audit("open", "Osi", path, mode, 0) < 0) {
return NULL;
int err;
int async_err = 0;
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
/* _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
Py_ssize_t
_Py_write(int fd, const void *buf, size_t count)
{
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
/* _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
HANDLE handle;
#endif
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
#ifdef MS_WINDOWS
handle = _Py_get_osfhandle(fd);
_PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
{
assert(is_tstate_valid(tstate));
- /* The caller must hold the GIL */
- assert(PyGILState_Check());
+ /* The caller must hold a thread state */
+ _Py_AssertHoldsTstate();
/* Call _PySys_Audit() in the context of the current thread state,
even if tstate is not the current thread state. */
_PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg)
{
assert(is_tstate_valid(tstate));
- /* The caller must hold the GIL */
- assert(PyGILState_Check());
+ /* The caller must hold a thread state */
+ _Py_AssertHoldsTstate();
/* Call _PySys_Audit() in the context of the current thread state,
even if tstate is not the current thread state. */
const PyConfig*
_Py_GetConfig(void)
{
- assert(PyGILState_Check());
PyThreadState *tstate = current_fast_get();
_Py_EnsureTstateNotNULL(tstate);
return _PyInterpreterState_GetConfig(tstate->interp);
#include "Python.h"
#include "pycore_time.h" // PyTime_t
+#include "pycore_pystate.h" // _Py_AssertHoldsTstate()
#include <time.h> // gmtime_r()
#ifdef HAVE_SYS_TIME_H
#endif
-// N.B. If raise_exc=0, this may be called without the GIL.
+// N.B. If raise_exc=0, this may be called without a thread state.
static int
py_get_system_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
{
assert(info == NULL || raise_exc);
if (raise_exc) {
- // raise_exc requires to hold the GIL
- assert(PyGILState_Check());
+ // raise_exc requires to hold a thread state
+ _Py_AssertHoldsTstate();
}
#ifdef MS_WINDOWS
#endif
-// N.B. If raise_exc=0, this may be called without the GIL.
+// N.B. If raise_exc=0, this may be called without a thread state.
static int
py_get_monotonic_clock(PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
{
assert(info == NULL || raise_exc);
if (raise_exc) {
- // raise_exc requires to hold the GIL
- assert(PyGILState_Check());
+ // raise_exc requires to hold a thread state
+ _Py_AssertHoldsTstate();
}
#if defined(MS_WINDOWS)
traceback_t *traceback;
_Py_hashtable_entry_t *entry;
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
/* get frames */
traceback = tracemalloc_traceback;
tracemalloc_clear_traces_unlocked(void)
{
// Clearing tracemalloc_filenames requires the GIL to call Py_DECREF()
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
set_reentrant(1);
void
_PyTraceMalloc_Fini(void)
{
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
tracemalloc_deinit();
}
return 0;
}
- assert(PyGILState_Check());
+ _Py_AssertHoldsTstate();
TABLES_LOCK();
if (!tracemalloc_config.tracing) {