On Wed, Dec 21, 2016 at 5:07 PM, Nick Coghlan <ncogh...@gmail.com> wrote: > On 21 December 2016 at 20:01, Erik Bray <erik.m.b...@gmail.com> wrote: >> >> On Wed, Dec 21, 2016 at 2:10 AM, Nick Coghlan <ncogh...@gmail.com> wrote: >> > Option 2: Similar to option 1, but using a custom type alias, rather >> > than >> > using a C99 bool directly >> > >> > The closest API we have to these semantics at the moment would be >> > PyGILState_Ensure, so the following API naming might work for option 2: >> > >> > Py_ensure_t >> > Py_ENSURE_NEEDS_INIT >> > Py_ENSURE_INITIALIZED >> > >> > Respectively, these would just be aliases for bool, false, and true. >> > >> > And then modify the proposed PyThread_tss_create and PyThread_tss_delete >> > APIs to accept a "Py_ensure_t *init_flag" in addition to their current >> > arguments. >> >> That all sounds good--between the two option 2 looks a bit more explicit. >> >> Though what about this? Rather than adding another type, the original >> proposal could be changed slightly so that Py_tss_t *is* partially >> defined as a struct consisting of a bool, with whatever the native TLS >> key is. E.g. >> >> typedef struct { >> bool init_flag; >> #if defined(_POSIX_THREADS) >> pthreat_key_t key; >> #elif defined (NT_THREADS) >> DWORD key; >> /* etc... */ >> } Py_tss_t; >> >> Then it's just taking Masayuki's original patch, with the global bool >> variables, and formalizing that by combining the initialized flag with >> the key, and requiring the semantics you described above for >> PyThread_tss_create/delete. >> >> For Python's purposes it seems like this might be good enough, with >> the more general purpose pthread_once-like functionality not required. > > > Aye, I also thought of that approach, but talked myself out of it since > there's no definable default value for pthread_key_t. However, C99 partial > initialisation may deal with that for us (by zeroing the memory without > actually assigning a typed value to it), and if it does, I agree it would be > better to handle the initialisation flag automatically rather than requiring > callers to do it.
I think I understand what you're saying here... To be clear, let me enumerate the three currently supported cases and how they're affected: 1) CPython's TLS: Defines -1 as an uninitialized key (by fact of the implementation--that the keys are integers starting from zero) 2) pthreads: Does not definite an uninitialized default value for keys, for reasons described at [1] under "Non-Idempotent Data Key Creation". I understand their reasoning, though I can't claim to know specifically what they mean when they say that some implementations would require the mutual-exclusion to be performed on pthread_getspecific() as well. I don't know that it applies here. 3) windows: The return value of TlsAlloc() is a DWORD (unsigned int) and [2] states that its value should be opaque. So in principle we can cover all cases with an opaque struct that contains, as its first member, an is_initialized flag. The tricky part is how to initialize the rest of the struct (containing the underlying implementation-specific key). For 1) and 3) it doesn't matter--it can just be zero. For 2) it's trickier because there's no defined constant value to initialize a pthread_key_t to. Per Nick's suggestion this can be worked around by relying on C99's initialization semantics. Per [3] section 6.7.8, clause 21: """ If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration. """ How objects with static storage are initialized is described in the previous page under clause 10, but in practice it boils down to what you would expect: Everything is initialized to zero, including nested structs and arrays. So as long as we can use this feature of C99 then I think that's the best approach. [1] http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_key_create.html [2] https://msdn.microsoft.com/en-us/library/windows/desktop/ms686801(v=vs.85).aspx [3] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/