<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2016-12-21 19:01 GMT+09:00 Erik Bray <span dir="ltr"><<a href="mailto:erik.m.bray@gmail.com" target="_blank"><span class="" style="" id=":1zj.1" tabindex="-1">erik</span>.m.bray@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail-HOEnZb"><div class="gmail-h5">On Wed, Dec 21, 2016 at 2:10 AM, Nick Coghlan <<a href="mailto:ncoghlan@gmail.com">ncoghlan@gmail.com</a>> wrote:<br>
> Ouch, I'd missed that, and I agree it's not a negligible implementation<br>
> detail - there are definitely applications embedding CPython out there that<br>
> rely on being able to run multiple Initialize/Finalize cycles in the same<br>
> process and have everything "just work". It also means using the<br>
> "PyThread_*" prefix for the initialisation tracking aspect would be<br>
> misleading, since the life cycle details are:<br>
><br>
> 1. Create the key for the first time if it has never been previously set in<br>
> the process<br>
> 2. Destroy and reinit if Py_Finalize gets called<br>
> 3. Destroy and reinit if a new subprocess is forked<br>
><br>
> It also means we can't use pthread_once even in the pthread TLS<br>
> implementation, since it doesn't provide those semantics.<br>
><br>
> So I see two main alternatives here.<br>
><br>
> Option 1: Modify the proposed PyThread_tss_create and PyThread_tss_delete<br>
> APIs to accept a "bool *init_flag" pointer in addition to their current<br>
> arguments.<br>
><br>
> If *init_flag is true, then PyThread_tss_create is a no-op, otherwise it<br>
> sets the flag to true after creating the key.<br>
> If *init_flag is false, then PyThread_tss_delete is a no-op, otherwise it<br>
> sets the flag to false after deleting the key.<br>
><br>
> Option 2: Similar to option 1, but using a custom type alias, rather than<br>
> using a C99 bool directly<br>
><br>
> The closest API we have to these semantics at the moment would be<br>
> PyGILState_Ensure, so the following API naming might work for option 2:<br>
><br>
>     Py_ensure_t<br>
>     Py_ENSURE_NEEDS_INIT<br>
>     Py_ENSURE_INITIALIZED<br>
><br>
> Respectively, these would just be aliases for bool, false, and true.<br>
><br>
> And then modify the proposed PyThread_tss_create and PyThread_tss_delete<br>
> APIs to accept a "Py_ensure_t *init_flag" in addition to their current<br>
> arguments.<br>
<br>
</div></div>That all sounds good--between the two option 2 looks a bit more explicit.<br>
<br>
Though what about this?  Rather than adding another type, the original<br>
proposal could be changed slightly so that Py_tss_t *is* partially<br>
defined as a struct consisting of a bool, with whatever the native TLS<br>
key is.   E.g.<br>
<br>
typedef struct {<br>
    bool init_flag;<br>
    #if defined(_POSIX_THREADS)<br>
    pthreat_key_t key;<br>
    #elif defined (NT_THREADS)<br>
    DWORD key;<br>
    /* etc... */<br>
} Py_tss_t;<br>
<br>
Then it's just taking Masayuki's original patch, with the global bool<br>
variables, and formalizing that by combining the initialized flag with<br>
the key, and requiring the semantics you described above for<br>
PyThread_tss_create/delete.<br>
<br>
For Python's purposes it seems like this might be good enough, with<br>
the more general purpose pthread_once-like functionality not required.<br>
<br>
Best,<br>
Erik</blockquote><div><br>Above mentioned, In currently <span class="" style="" id=":1zj.2" tabindex="-1">TLS</span> API, the thread key uses -1 as defined invalid value. If new <span class="" style="" id=":1zj.3" tabindex="-1">TLS</span> API inherits the specifications that the key requires defined invalid value, putting key and flag into one structure seems correct as semantics. In this case, I think <span class="" style="" id=":1zj.4" tabindex="-1">TLS</span> API should supply the defined invalid value (like <span class="" style="" id=":1zj.5" tabindex="-1">PTHREAD</span>_ONCE_<span class="" style="" id=":1zj.6" tabindex="-1">INIT</span>) to API users.<br></div></div>Moreover, the structure has an opportunity to assert that the thread key type is the opaque using field name. I think to the suggestion that has effect to improve the understandability of the API because good field name can give that reading and writing to the key seems to be incorrect (even if API users don't read the precautionary statement).<br><br></div><div class="gmail_extra">Have a nice holiday!<br></div><div class="gmail_extra"><span class="" style="" id=":1zj.7" tabindex="-1">Masayuki</span><br></div></div>