Skip to content

Commit 1376eb0

Browse files
bstaleticwjakob
authored andcommitted
Free tstate on python 3.7+ on finalize_interpreter (#2020)
1 parent fb910ae commit 1376eb0

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

include/pybind11/detail/internals.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ inline PyObject *make_object_base_type(PyTypeObject *metaclass);
2525
# define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get((key))
2626
# define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set((key), (value))
2727
# define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set((key), nullptr)
28+
# define PYBIND11_TLS_FREE(key) PyThread_tss_free(key)
2829
#else
2930
// Usually an int but a long on Cygwin64 with Python 3.x
3031
# define PYBIND11_TLS_KEY_INIT(var) decltype(PyThread_create_key()) var = 0
@@ -43,6 +44,7 @@ inline PyObject *make_object_base_type(PyTypeObject *metaclass);
4344
# define PYBIND11_TLS_REPLACE_VALUE(key, value) \
4445
PyThread_set_key_value((key), (value))
4546
# endif
47+
# define PYBIND11_TLS_FREE(key) (void)key
4648
#endif
4749

4850
// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly
@@ -108,6 +110,16 @@ struct internals {
108110
#if defined(WITH_THREAD)
109111
PYBIND11_TLS_KEY_INIT(tstate);
110112
PyInterpreterState *istate = nullptr;
113+
~internals() {
114+
// This destructor is called *after* Py_Finalize() in finalize_interpreter().
115+
// That *SHOULD BE* fine. The following details what happens whe PyThread_tss_free is called.
116+
// PYBIND11_TLS_FREE is PyThread_tss_free on python 3.7+. On older python, it does nothing.
117+
// PyThread_tss_free calls PyThread_tss_delete and PyMem_RawFree.
118+
// PyThread_tss_delete just calls TlsFree (on Windows) or pthread_key_delete (on *NIX). Neither
119+
// of those have anything to do with CPython internals.
120+
// PyMem_RawFree *requires* that the `tstate` be allocated with the CPython allocator.
121+
PYBIND11_TLS_FREE(tstate);
122+
}
111123
#endif
112124
};
113125

@@ -138,7 +150,7 @@ struct type_info {
138150
};
139151

140152
/// Tracks the `internals` and `type_info` ABI version independent of the main library version
141-
#define PYBIND11_INTERNALS_VERSION 3
153+
#define PYBIND11_INTERNALS_VERSION 4
142154

143155
/// On MSVC, debug and release builds are not ABI-compatible!
144156
#if defined(_MSC_VER) && defined(_DEBUG)

0 commit comments

Comments
 (0)