@@ -18,6 +18,25 @@ inline PyTypeObject *make_static_property_type();
18
18
inline PyTypeObject *make_default_metaclass ();
19
19
inline PyObject *make_object_base_type (PyTypeObject *metaclass);
20
20
21
+ // The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new
22
+ // Thread Specific Storage (TSS) API.
23
+ #if PY_VERSION_HEX >= 0x03070000
24
+ #define PYBIND11_TLS_KEY_INIT (var ) Py_tss_t *var = nullptr
25
+ #define PYBIND11_TLS_GET_VALUE (key ) PyThread_tss_get((key))
26
+ #define PYBIND11_TLS_REPLACE_VALUE (key, value ) PyThread_tss_set((key), (tstate))
27
+ #define PYBIND11_TLS_DELETE_VALUE (key ) PyThread_tss_set((key), nullptr )
28
+ #else
29
+ // Usually an int but a long on Cygwin64 with Python 3.x
30
+ #define PYBIND11_TLS_KEY_INIT (var ) decltype (PyThread_create_key()) var = 0
31
+ #define PYBIND11_TLS_GET_VALUE (key ) PyThread_get_key_value((key))
32
+ #if PY_MAJOR_VERSION < 3
33
+ #define PYBIND11_TLS_REPLACE_VALUE (key, value ) do { PyThread_delete_key_value ((key)); PyThread_set_key_value ((key), (value)); } while (false )
34
+ #else
35
+ #define PYBIND11_TLS_REPLACE_VALUE (key, value ) PyThread_set_key_value((key), (value))
36
+ #endif
37
+ #define PYBIND11_TLS_DELETE_VALUE (key ) PyThread_set_key_value((key), nullptr )
38
+ #endif
39
+
21
40
// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly
22
41
// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module
23
42
// even when `A` is the same, non-hidden-visibility type (e.g. from a common include). Under
@@ -79,7 +98,7 @@ struct internals {
79
98
PyTypeObject *default_metaclass;
80
99
PyObject *instance_base;
81
100
#if defined(WITH_THREAD)
82
- decltype (PyThread_create_key()) tstate = 0; // Usually an int but a long on Cygwin64 with Python 3.x
101
+ PYBIND11_TLS_KEY_INIT ( tstate);
83
102
PyInterpreterState *istate = nullptr ;
84
103
#endif
85
104
};
@@ -111,7 +130,7 @@ struct type_info {
111
130
};
112
131
113
132
// / Tracks the `internals` and `type_info` ABI version independent of the main library version
114
- #define PYBIND11_INTERNALS_VERSION 1
133
+ #define PYBIND11_INTERNALS_VERSION 2
115
134
116
135
#if defined(WITH_THREAD)
117
136
# define PYBIND11_INTERNALS_KIND " "
@@ -166,8 +185,17 @@ PYBIND11_NOINLINE inline internals &get_internals() {
166
185
#if defined(WITH_THREAD)
167
186
PyEval_InitThreads ();
168
187
PyThreadState *tstate = PyThreadState_Get ();
169
- internals_ptr->tstate = PyThread_create_key ();
170
- PyThread_set_key_value (internals_ptr->tstate , tstate);
188
+ #if PY_VERSION_HEX >= 0x03070000
189
+ internals_ptr->tstate = PyThread_tss_alloc ();
190
+ if (!internals_ptr->tstate || PyThread_tss_create (internals_ptr->tstate ))
191
+ pybind11_fail (" get_internals: could not successfully initialize the TSS key!" );
192
+ PyThread_tss_set (internals_ptr->tstate , tstate);
193
+ #else
194
+ internals_ptr->tstate = PyThread_create_key ();
195
+ if (internals_ptr->tstate == -1 )
196
+ pybind11_fail (" get_internals: could not successfully initialize the TLS key!" );
197
+ PyThread_set_key_value (internals_ptr->tstate , tstate);
198
+ #endif
171
199
internals_ptr->istate = tstate->interp ;
172
200
#endif
173
201
builtins[id] = capsule (internals_pp);
0 commit comments