|
Boost : |
From: John Maddock (john_at_[hidden])
Date: 2004-07-29 05:42:33
> > 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!).
I agree violently that the calling thread must have been started with
__beginthread. I can't think of any threading lib where this is not the
case - even exception handling doesn't work in a thread unless it was
created with __beginthread. This is very different however from requiring
that the thread was created with Boost.Threads, which is what was being
suggested.
As for C runtime initialisation, I believe that this is a non-issue: the
slot is allocated (TlsAlloc) when the lib is loaded, but no C runtime calls
are made at this point. Calls to the C runtime are only made when the slot
is first *accessed* at which point the object gets created with a call to
new, if it does not already exist.
When it comes to cleanup we may have a problem if the exe is statically
linked, but if it's dynamically linked then Boost.Threads cleanup *will* get
called before that of the runtime on which it depends.
I need to think some more about statically linked executables...
John.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk