|
Boost : |
From: Johan Nilsson (johan.nilsson_at_[hidden])
Date: 2004-06-04 06:40:32
"Michael Glassford" <glassfordm_at_[hidden]> wrote in message
news:c9nemm$gt8$1_at_sea.gmane.org...
> "Johan Nilsson" <johan.nilsson_at_[hidden]> wrote in message
> news:c9mk92$815$1_at_sea.gmane.org...
> >
> > "Michael Glassford" <glassfordm_at_[hidden]> wrote in message
> > news:c9kodd$krt$1_at_sea.gmane.org...
> > > "Johan Nilsson" <johan.nilsson_at_[hidden]> wrote in message
> > > news:c9k069$9jf$1_at_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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk