Boost logo

Boost :

From: Roland (roland.schwarz_at_[hidden])
Date: 2004-08-04 10:58:58


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)

>
> 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?)
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.)

>
> 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.)

>
> 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.

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.

>
> 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.

Roland


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