Boost logo

Boost :

From: Michael Glassford (glassfordm_at_[hidden])
Date: 2004-08-05 14:31:39


I thought I had sent this yesterday, but it appears that I didn't.
Though it's a little late, here it is anyway.

Roland wrote:

> On Wed, 04 Aug 2004 10:50:47 -0400 Michael Glassford <glassfordm_at_[hidden]> wrote:
>
>
>>Having experimented a bit and thought a bit, here's my take on how this
>>could work:
>>
>>1) Functions on_process_enter() and on_thread_enter() are unnecessary.
>
>
> I am not convinced about on_process_enter. This could be the place to allocate
> the slot without the need for any locking. (and the call to atexit)

I'm not worried about locking. Locking is needed for at_thread_exit(),
since it can be called from multiple threads simultaneously. Since
locking will already be necessary there, it makes sense to use it for
the on_process_*() and on_thread_*() functions, especially since they
are also available for users to call and we can't guarantee they will be
called in a thread-safe manner, either.

>>2) DllMain() and tls_callback() are needed only to call on_thread_exit().
>
>
> I agree on that.
>
>
>>3) Function at_thread_exit() schedules a tss cleanup task that needs to
>>be run for a thread that uses tss. The first time it is executed it also
>>calls:
>>
>> atexit(on_process_exit);
>> atexit(on_thread_exit);
>>
>>to schedule cleanup for the main thread before destructors of global
>>objects are run and to schedule on_process_exit() (which calls TlsFree()).
>
>
> I have some reservations of how you will make sure, that the first call is in
> the context of the main thread. If not the call to atexit might be erreonous.
> (Is atexit really multithread safe?)

Good point. I'll make that modification.

> This is why I schedule the call to atexit within .CRT$XCU.
> (BTW the initialization of the slot could very well also be from this place,
> the choice to do it earlier was only to have the slot well before any constructors
> were run.)

I don't think that's a big problem either if locking is assumed. It
makes as much sense to allocate the slot when it is first used; that way
if Boost.Threads tss is never used a tls slot is never allocated.

>>4) In addition, to provide some cleanup support for compilers that don't
>>yet have tls_callback() support, the thread class continues to call
>>on_thread_exit() after the thread function exits for threads created by
>>Boost.Threads.
>
>
> Yes this is very reasonable. I would even suggest that this is the default behaviour
> and only when the thread is foreign, the callback shall be used.
> However this will require some (thread specific) flag that can be interrogated
> by the tls_callback implementation whether boost already has called on_thread_exit.
> (Or see the comment further below.)

I'm assuming that on_thread_exit can be called multiple times per thread
(as it can with the current implementation). The thread-specific flag is
the tls slot's value: if it's zero, no cleanup is needed.

>>This should make unification of the VC++ 7.1 and 6 versions easier; the
>>only difference would be the startup code needed to call
>>on_tls_prepare(), I believe.
>
>
> I think your original semantics of the three:
> void on_process_enter(void);
> void on_process_exit(void);
> void on_thread_exit(void);
>
> is already perfect.
> void main {
> on_process_enter();
>
> ....
>
> on_process_exit();
> }
>
> and calling from the end of the thread proc:
> on_thread_exit.
>
>
> I personally would like to see the tls implementation exposing only
> these and relying on the compiler specific files doing the rest.
> I can even think of on_thread_exit having an internal one shot flag which
> simply prevent it running multiple times in case e.g. boost.thread and
> the callback (or a user code) is calling in multiple times.

As I said, the tls slot itself essentially does this.

> What do you think?
>
> BTW.: Unification is not so hard at all, given the current version.
> I am just dealing with the different semantics of the initializers.
> Newer ones simply have a return value which may abort initialization
> prematurely. But this is rather trivial to solve for.

OK.

>>Comments?
>>
>>
>>Also, I was wondering: has anyone tried this on VC++ 7.0?
>
>
> Not yet. But I still have a version around on my machine.
> What still puzzles me, that there were reports that the solution
> does not work with __declspec(thread).
> I will dive into this issue (tomorrow) and also the static binding to a user DLL
> which also has to betested out yet.

Let me know what you find out about both of these.

Thanks,

Mike


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