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

+