diff --git a/pep-0539.txt b/pep-0539.txt index 143ee3ed7..d7bba3677 100644 --- a/pep-0539.txt +++ b/pep-0539.txt @@ -52,12 +52,12 @@ These would be superseded by a new set of analogous functions:: PyAPI_FUNC(int) PyThread_tss_create(Py_tss_t *key) PyAPI_FUNC(void) PyThread_tss_delete(Py_tss_t *key) - PyAPI_FUNC(int) PyThread_tss_set(Py_tss_t key, void *value) - PyAPI_FUNC(void *) PyThread_tss_get(Py_tss_t key) - PyAPI_FUNC(void) PyThread_tss_delete_value(Py_tss_t key) + PyAPI_FUNC(int) PyThread_tss_set(Py_tss_t *key, void *value) + PyAPI_FUNC(void *) PyThread_tss_get(Py_tss_t *key) + PyAPI_FUNC(void) PyThread_tss_delete_value(Py_tss_t *key) PyAPI_FUNC(void) PyThread_ReInitTSS(void) -The specification also adds three new features: +The specification also adds a few new features: * A new type ``Py_tss_t``--an opaque type the definition of which may depend on the underlying TLS implementation. It is defined:: @@ -73,12 +73,18 @@ The specification also adds three new features: * A constant default value for ``Py_tss_t`` variables, ``Py_tss_NEEDS_INIT``. -* A new inline function:: +* Three new functions:: - static inline bool PyThread_tss_is_created(Py_tss_t key) + PyAPI_FUNC(Py_tss_t *) PyThread_tss_alloc(void) + PyAPI_FUNC(void) PyThread_tss_free(Py_tss_t *key) + PyAPI_FUNC(bool) PyThread_tss_is_created(Py_tss_t *key) - which returns ``true`` if the given ``Py_tss_t`` has been initialized - (i.e. by ``PyThread_tss_create``). + The first two are needed for dynamic (de-)allocation of a `Py_tss_t`, + particularly in extension modules built with `Py_LIMITED_API`, where + static allocation of this type is not possible due to its implementation + being opaque at build time. ``PyThread_tss_is_created`` returns ``true`` + if the given ``Py_tss_t`` has been initialized (i.e. by + ``PyThread_tss_create``). The new ``PyThread_tss_`` functions are almost exactly analogous to their original counterparts with a minor difference: Whereas @@ -90,8 +96,11 @@ by ``Py_tss_NEEDS_INIT``. The returned status status code is zero on success and non-zero on failure. The meanings of non-zero status codes are not otherwise defined by this specification. -Similarly ``PyThread_tss_delete`` is passed a ``Py_tss_t*`` whereas -previouly the key was passed to ``PyThread_delete_key`` by value. +Similarly the other ``PyThread_tss_`` functions are passed a ``Py_tss_t*`` +whereas previously the key was passed by value. This change is necessary, as +being an opaque type, the ``Py_tss_t`` type could hypothetically be almost +any size. This is especially necessary for extension modules built with +``Py_LIMITED_API``, where the size of the type is not known. The old ``PyThread_*_key*`` functions will be marked as deprecated in the documentation, but will not generate runtime deprecation warnings. @@ -112,18 +121,18 @@ With the proposed changes, a TSS key is initialized like:: The initialization state of the key can then be checked like:: - assert(PyThread_tss_is_created(tss_key)); + assert(PyThread_tss_is_created(&tss_key)); The rest of the API is used analogously to the old API:: int the_value = 1; - if (PyThread_tss_get(tss_key) == NULL) { - PyThread_tss_set(tss_key, (void *)&the_value); - assert(PyThread_tss_get(tss_key) != NULL); + if (PyThread_tss_get(&tss_key) == NULL) { + PyThread_tss_set(&tss_key, (void *)&the_value); + assert(PyThread_tss_get(&tss_key) != NULL); } /* ... once done with the key ... */ PyThread_tss_delete(&tss_key); - assert(!PyThread_tss_is_created(tss_key)); + assert(!PyThread_tss_is_created(&tss_key)); Motivation