
"Michael Glassford" <glassfordm@hotmail.com> wrote in message news:c9nemm$gt8$1@sea.gmane.org...
"Johan Nilsson" <johan.nilsson@esrange.ssc.se> wrote in message news:c9mk92$815$1@sea.gmane.org...
"Michael Glassford" <glassfordm@hotmail.com> wrote in message news:c9kodd$krt$1@sea.gmane.org...
"Johan Nilsson" <johan.nilsson@esrange.ssc.se> wrote in message news:c9k069$9jf$1@sea.gmane.org...
[snip]
An alternative could be to have Boost.Threads automatically create a background thread to periodically collect unowned thread-specific data.
This could also be used in addition to lazy cleanup instead of as an alternative, and seems to have the same problems.
Implementing the solution another poster mentioned (have a background thread wait either on thread termination or an event signalling a new thread request TSS data) would be better. Or why not implement a catch (...) around the call to the threads user's provided thread entry and free data when it returns - but that would preclude users to create threads directly and still use thread_specific_ptr's. Hmmm ... or is that impossible in the current implementation as well?
Now if boost threads could have priority assigned to them to make this a (corresponding to) THREAD_PRIORITY_IDLE thread - is that in the works?
The (unfinished) changes on the thread_dev branch do implement thread priorties. They won't make it into the next Boost release, but I hope they will be in the one after that.
Not a problem in this case; you could just use (the boost equivalent of): // pseudo pseudo-code #if defined (WIN32) ::SetThreadPriority(...); #else #error <appropriate error message> #endif [snip]
Highly theoretical:
1. Thread A is created with id:1 2. Thread A" creates thread_specificic_ptr (first time), implicitly allocating TLS slot. 3. Thread A exits 4. Thread B is created, gettting the recycled id of the first thread (id:1) 5. Thread B creates thread_specific_ptr; this is the first time so the implementation now also tries to perform a 'lazy' cleanup of any unowned data. There are still data allocated by Thread A, but this is mapped through the thread's id and so can't be detected as ready for collection.
I follow as far as this.
Thread B can still create it's own data,
How does thread B know that it needs to create its own data--i.e., what prevents it from thinking that thread A's data is its own and using it?
By pure magic I suppose ... ;-) Seriously, I haven't checked the thread_specific_ptr implementation. Previously I've always been under the impression that if calling TlsGetValue(<tls index>) return NULL and GetLastError() == NO_ERROR, the calling threads slot is uninitialized => create whatever and store pointer. The thread id as mapped by the suggestion above is only used for deleting "unowned data". References to the data is stored globally, protected by a synchronization object and mapped per thread-id. This "meta"-data is not used for _accessing_ the data.
Here's a specific case I have in mind: the implementation of the thread class on the thread_dev branch. In this implmemtation, the thread class has become a handle class that holds a reference-counted pointer to a thread_data class. When a thread class is created, it gets access to the thread_data class for the thread using a global static thread_specific_ptr. In the scenario you outline above, when a thread object created on Thread B tries to access its thread data through this thread_specific_ptr, it will get the thread data for thread A, which is a Bad Thing.
If it accesses the data through it's own id <-> data map, yes. Not if it leaves that to the operating systems's service internally (TlsGetValue). I might be missing something though. [snip]
Yes, but that's still forcing the user to use a "special" dll just
for that
purpose.
Not necessarily. If the user's code is in a dll, its own dllmain could be used; or the dllmain of the "pseudo dll" that is created on the fly could be used.
Sorry, I meant you're forcing the user to _use a dll_ for that purpose (i.e. not necessarily a "special" one). // Johan