Boost logo

Boost :

From: Roland (roland.schwarz_at_[hidden])
Date: 2004-07-28 09:26:39


On Wed, 28 Jul 2004 13:25:21 +0100 John Maddock <john_at_[hidden]> wrote:

> I agree, and it should be able to clean up non-boost threads as well -
> consider what happens if you're writing a library, and not a program - you
> then have no control over who creates threads or how they do so. I believe
> it would be unacceptable to say "you can only use this library if you also
> use Boost.Threads"; in such cases thread_specific_ptr is exceptionally
> useful IMO.

While having heard this argument quite often, I still do not understand how this
can ever work (in a reliable way).

Say you have a peace of code located in module A that is starting a thread by
whatever means (System thread e.g.).

Now in your module B you have a (global) TSS variable.
A calls into B.
When should the TSS be initialized? On first use? I am afraid that is not trivially
possible, since you (as far as I understand on WIndows) will need to
acquire a slot for this variable when the process starts up (normally in
DLL_PROCESS_ATTACH).
You might argue that you can have a global object in B whose constructor
can handle this. Ok this would work. You can acquire the Slot during initialization,
and can acquire your data on the heap on first use.

_But_ what is about c-runtime initialisation?
Perhaps I am a little bit to paranoid about this but the per thread data holds items like

> unsigned long _tdoserrno; /* _doserrno value */
> unsigned int _fpds; /* Floating Point data segment */
> unsigned long _holdrand; /* rand() seed value */
> char * _token; /* ptr to strtok() token */

to cite only a few, that are clearly related to a couple of runtime lib functions.

How can you ever be sure the c-runtime will behave correctly when
these are not available/initialized for your thread (note you did never call _beginthread!).

So what I think is:
One should not assume that your piece of code is thread safe (located in B) when making
use of the c-runtime AND you do not know wheter the original call (located in A) started
the thread by _beginthread. You even should not try to use the runtime lib in that case.
A TSS implementation thus should "require" a certain (minimum) method for starting threads.
I propose a method that has correct runtime initialization at minimum. When this
requirement is not fullfilled your module can not be said "truly" thread safe.

Note: If the TSS implementation AND the objects contained in a thread slot are
independent from c-runtime the above discussion does not apply. But practically
I think this is a much too severe restriction!

View it another way: the TSS cleanup code has to consider any resources it is
using at cleanup time. c-runtime struct _tiddata, beeing one of the important ones.

Roland


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk