bpo-25658: Implement PEP 539 for Thread Specific Storage (TSS) API (G… · python/cpython@731e189 (original) (raw)
`@@ -1192,3 +1192,160 @@ These functions are only intended to be used by advanced debugging tools.
`
1192
1192
` Return the next thread state object after tstate from the list of all such
`
1193
1193
`` objects belonging to the same :c:type:PyInterpreterState
object.
``
1194
1194
``
``
1195
+
``
1196
`+
.. _thread-local-storage:
`
``
1197
+
``
1198
`+
Thread Local Storage Support
`
``
1199
`+
============================
`
``
1200
+
``
1201
`+
.. sectionauthor:: Masayuki Yamamoto ma3yuki.8mamo10@gmail.com
`
``
1202
+
``
1203
`+
The Python interpreter provides low-level support for thread-local storage
`
``
1204
`+
(TLS) which wraps the underlying native TLS implementation to support the
`
``
1205
`` +
Python-level thread local storage API (:class:threading.local
). The
``
``
1206
`+
CPython C level APIs are similar to those offered by pthreads and Windows:
`
``
1207
`` +
use a thread key and functions to associate a :c:type:void\*
value per
``
``
1208
`+
thread.
`
``
1209
+
``
1210
`+
The GIL does not need to be held when calling these functions; they supply
`
``
1211
`+
their own locking.
`
``
1212
+
``
1213
`` +
Note that :file:Python.h
does not include the declaration of the TLS APIs,
``
``
1214
`` +
you need to include :file:pythread.h
to use thread-local storage.
``
``
1215
+
``
1216
`+
.. note::
`
``
1217
`+
None of these API functions handle memory management on behalf of the
`
``
1218
`` +
:c:type:void\*
values. You need to allocate and deallocate them yourself.
``
``
1219
`` +
If the :c:type:void\*
values happen to be :c:type:PyObject\*
, these
``
``
1220
`+
functions don't do refcount operations on them either.
`
``
1221
+
``
1222
`+
.. _thread-specific-storage-api:
`
``
1223
+
``
1224
`+
Thread Specific Storage (TSS) API
`
``
1225
`+
`
``
1226
+
``
1227
`+
TSS API is introduced to supersede the use of the existing TLS API within the
`
``
1228
`` +
CPython interpreter. This API uses a new type :c:type:Py_tss_t
instead of
``
``
1229
`` +
:c:type:int
to represent thread keys.
``
``
1230
+
``
1231
`+
.. versionadded:: 3.7
`
``
1232
+
``
1233
`` +
.. seealso:: "A New C-API for Thread-Local Storage in CPython" (:pep:539
)
``
``
1234
+
``
1235
+
``
1236
`+
.. c:type:: Py_tss_t
`
``
1237
+
``
1238
`+
This data structure represents the state of a thread key, the definition of
`
``
1239
`+
which may depend on the underlying TLS implementation, and it has an
`
``
1240
`+
internal field representing the key's initialization state. There are no
`
``
1241
`+
public members in this structure.
`
``
1242
+
``
1243
`` +
When :ref:Py_LIMITED_API <stable>
is not defined, static allocation of
``
``
1244
`` +
this type by :c:macro:Py_tss_NEEDS_INIT
is allowed.
``
``
1245
+
``
1246
+
``
1247
`+
.. c:macro:: Py_tss_NEEDS_INIT
`
``
1248
+
``
1249
`` +
This macro expands to the default value for :c:type:Py_tss_t
variables.
``
``
1250
`` +
Note that this macro won't be defined with :ref:Py_LIMITED_API <stable>
.
``
``
1251
+
``
1252
+
``
1253
`+
Dynamic Allocation
`
``
1254
`+
`
``
`1255`
`+`
``
`1256`
`` +
Dynamic allocation of the :c:type:`Py_tss_t`, required in extension modules
``
``
`1257`
`` +
built with :ref:`Py_LIMITED_API <stable>`, where static allocation of this type
``
``
`1258`
`+
is not possible due to its implementation being opaque at build time.
`
``
`1259`
`+`
``
`1260`
`+`
``
`1261`
`+
.. c:function:: Py_tss_t* PyThread_tss_alloc()
`
``
`1262`
`+`
``
`1263`
`+
Return a value which is the same state as a value initialized with
`
``
`1264`
`` +
:c:macro:`Py_tss_NEEDS_INIT`, or *NULL* in the case of dynamic allocation
``
``
`1265`
`+
failure.
`
``
`1266`
`+`
``
`1267`
`+`
``
`1268`
`+
.. c:function:: void PyThread_tss_free(Py_tss_t *key)
`
``
`1269`
`+`
``
`1270`
`` +
Free the given *key* allocated by :c:func:`PyThread_tss_alloc`, after
``
``
`1271`
`` +
first calling :c:func:`PyThread_tss_delete` to ensure any associated
``
``
`1272`
`+
thread locals have been unassigned. This is a no-op if the *key*
`
``
`1273`
`` +
argument is `NULL`.
``
``
`1274`
`+`
``
`1275`
`+
.. note::
`
``
`1276`
`+
A freed key becomes a dangling pointer, you should reset the key to
`
``
`1277`
`` +
`NULL`.
``
``
`1278`
`+`
``
`1279`
`+`
``
`1280`
`+
Methods
`
``
`1281`
`+
`
``
1282
+
``
1283
`+
The parameter key of these functions must not be NULL. Moreover, the
`
``
1284
`` +
behaviors of :c:func:PyThread_tss_set
and :c:func:PyThread_tss_get
are
``
``
1285
`` +
undefined if the given :c:type:Py_tss_t
has not been initialized by
``
``
1286
`` +
:c:func:PyThread_tss_create
.
``
``
1287
+
``
1288
+
``
1289
`+
.. c:function:: int PyThread_tss_is_created(Py_tss_t *key)
`
``
1290
+
``
1291
`` +
Return a non-zero value if the given :c:type:Py_tss_t
has been initialized
``
``
1292
`` +
by :c:func:PyThread_tss_create
.
``
``
1293
+
``
1294
+
``
1295
`+
.. c:function:: int PyThread_tss_create(Py_tss_t *key)
`
``
1296
+
``
1297
`+
Return a zero value on successful initialization of a TSS key. The behavior
`
``
1298
`+
is undefined if the value pointed to by the key argument is not
`
``
1299
`` +
initialized by :c:macro:Py_tss_NEEDS_INIT
. This function can be called
``
``
1300
`+
repeatedly on the same key -- calling it on an already initialized key is a
`
``
1301
`+
no-op and immediately returns success.
`
``
1302
+
``
1303
+
``
1304
`+
.. c:function:: void PyThread_tss_delete(Py_tss_t *key)
`
``
1305
+
``
1306
`+
Destroy a TSS key to forget the values associated with the key across all
`
``
1307
`+
threads, and change the key's initialization state to uninitialized. A
`
``
1308
`+
destroyed key is able to be initialized again by
`
``
1309
`` +
:c:func:PyThread_tss_create
. This function can be called repeatedly on
``
``
1310
`+
the same key -- calling it on an already destroyed key is a no-op.
`
``
1311
+
``
1312
+
``
1313
`+
.. c:function:: int PyThread_tss_set(Py_tss_t *key, void *value)
`
``
1314
+
``
1315
`` +
Return a zero value to indicate successfully associating a :c:type:void\*
``
``
1316
`+
value with a TSS key in the current thread. Each thread has a distinct
`
``
1317
`` +
mapping of the key to a :c:type:void\*
value.
``
``
1318
+
``
1319
+
``
1320
`+
.. c:function:: void* PyThread_tss_get(Py_tss_t *key)
`
``
1321
+
``
1322
`` +
Return the :c:type:void\*
value associated with a TSS key in the current
``
``
1323
`+
thread. This returns NULL if no value is associated with the key in the
`
``
1324
`+
current thread.
`
``
1325
+
``
1326
+
``
1327
`+
.. _thread-local-storage-api:
`
``
1328
+
``
1329
`+
Thread Local Storage (TLS) API
`
``
1330
`+
`
``
1331
+
``
1332
`+
.. deprecated:: 3.7
`
``
1333
`+
This API is superseded by
`
``
1334
`` +
:ref:Thread Specific Storage (TSS) API <thread-specific-storage-api>
.
``
``
1335
+
``
1336
`+
.. note::
`
``
1337
`+
This version of the API does not support platforms where the native TLS key
`
``
1338
is defined in a way that cannot be safely cast to ``int``. On such platforms,
``
1339
`` +
:c:func:PyThread_create_key
will return immediately with a failure status,
``
``
1340
`+
and the other TLS functions will all be no-ops on such platforms.
`
``
1341
+
``
1342
`+
Due to the compatibility problem noted above, this version of the API should not
`
``
1343
`+
be used in new code.
`
``
1344
+
``
1345
`+
.. c:function:: int PyThread_create_key()
`
``
1346
`+
.. c:function:: void PyThread_delete_key(int key)
`
``
1347
`+
.. c:function:: int PyThread_set_key_value(int key, void *value)
`
``
1348
`+
.. c:function:: void* PyThread_get_key_value(int key)
`
``
1349
`+
.. c:function:: void PyThread_delete_key_value(int key)
`
``
1350
`+
.. c:function:: void PyThread_ReInitTLS()
`
``
1351
+