[boost.thread] Allowed lifetime of a thread?

While considering various ways to get rid of the remaining intentional memory leak of the tss implementation, I came upon the following question: How long may a thread access it's tss storage anyway? I did not find anything in the documentation about the topic. Looking into the destructor of thread_specific_ptr reveals ~thread_specific_ptr() { reset(); } which in turn implies, that the thread(s) which are using it should have already terminated, when the main thread has exited (called its dtor list). Now when one has control over the lifetime of the threads this poses no problem, since they simply need to be terminated before main() ends. The situation is completely different when writing a piece of code (a library) that has to use tss and shall work with foreign threads too. The library writer in this case has no control over the lifetime of the threads (native or not). So I am wondering if it is possible to refine the inner workings of the thread_specific_ptr without changing the interface to account for these cases? Perhaps only a static pointer should be embedded that points to dynamic memory that will not be touched by destructor calls, but controlled in lifetime be real thread-detachements. (The last one frees everything which is really global.) How is the situation for other libraries, say e.g. pthreads? Are they allowed to run after main ended? Or is this simply considered bad programm behaviour? Any comments? Roland

Roland wrote:
While considering various ways to get rid of the remaining intentional memory leak of the tss implementation, I came upon the following question:
How long may a thread access it's tss storage anyway?
Process termination aside for a moment, as long as it can (up to PTHREAD_DESTRUCTOR_ITERATIONS).
I did not find anything in the documentation about the topic.
Looking into the destructor of thread_specific_ptr reveals ~thread_specific_ptr() { reset(); }
The issue here is reuse of TSD keys. For keys without cleanup (null TSD destructor), implementations shall ensure that appls see nulls upon reuse. In the case of keys WITH cleanup (non- null TSD destuctors), it is the responsibility of appls to clear the slots (in all relevant threads) and perform cleanup prior to TSD key destruction. http://google.com/groups?selm=406ECF36.226C8B99%40web.de (Subject: Re: TSD key reuse) [...]
How is the situation for other libraries, say e.g. pthreads? Are they allowed to run after main ended?
Main (initial) *thread* is just a thread, nothing special. Main *function* is special. Return from main is just like calling exit() -- it evaporates all threads without any thread cleanup. OTOH, mere termination of main/initial thread (by means of pthread_exit() or thread cancellation), has no effect with respect to other threads. regards, alexander.

On Mon, 09 Aug 2004 11:42:44 +0200 Alexander Terekhov <terekhov@web.de> wrote:
Roland wrote:
While considering various ways to get rid of the remaining intentional memory leak of the tss implementation, I came upon the following question:
How long may a thread access it's tss storage anyway?
Process termination aside for a moment, as long as it can (up to PTHREAD_DESTRUCTOR_ITERATIONS).
I did not find anything in the documentation about the topic.
Looking into the destructor of thread_specific_ptr reveals ~thread_specific_ptr() { reset(); }
The issue here is reuse of TSD keys. For keys without cleanup (null TSD destructor), implementations shall ensure that appls see nulls upon reuse. In the case of keys WITH cleanup (non- null TSD destuctors), it is the responsibility of appls to clear the slots (in all relevant threads) and perform cleanup prior to TSD key destruction.
http://google.com/groups?selm=406ECF36.226C8B99%40web.de (Subject: Re: TSD key reuse)
This post mentions the necessity that ~thread_specific_ptr needs to deallocate the slot. Is this really necessary? I see two different areas of concern: 1) Process termination: Not really a need to free the native slot, since the process is going away anyways. Also I think no current memory debugging utility will bother with native slots. 2) DLL detachment: It is essential to free the native slot, since not doing so prevents reuse. However this will be bad for connected threads. There seems to exist some principal coupling between the lifetime of a thread and lifetime of a DLL, which is not enforced by the operating system.
[...]
How is the situation for other libraries, say e.g. pthreads? Are they allowed to run after main ended?
Main (initial) *thread* is just a thread, nothing special. Main *function* is special. Return from main is just like calling exit() -- it evaporates all threads without any thread cleanup. OTOH, mere termination of main/initial thread (by means of pthread_exit() or thread cancellation), has no effect with respect to other threads.
This sounds interesting to me. It is really possible to use pthread_exit() to exit the main thread? And what happens then? Are the global destuctors called? Or are they held off until the last thread exited? Roland

Roland wrote: [...]
http://google.com/groups?selm=406ECF36.226C8B99%40web.de (Subject: Re: TSD key reuse)
This post mentions the necessity that ~thread_specific_ptr needs to deallocate the slot. Is this really necessary?
Windows zaps the slots asynchronously if you do TlsFree. http://groups.google.com/groups?selm=3f5d1aee%241%40news.microsoft.com <quote author=Neill Clift [MSFT]> we do cross thread clearing of tls slots when its deleted by one thread. </quote> This is needed for thread_specific_ptr< T, no_cleanup > objects.
I see two different areas of concern: 1) Process termination: Not really a need to free the native slot, since the process is going away anyways.
Right.
Also I think no current memory debugging utility will bother with native slots. 2) DLL detachment: It is essential to free the native slot, since not doing so prevents reuse.
Right.
However this will be bad for connected threads. There seems to exist some principal coupling between the lifetime of a thread and lifetime of a DLL, which is not enforced by the operating system.
The entire application shall stop using the DLL by the time it unloads it. "dll_fini" will deallocate the slots. Now see above. Having "thread insensible TSD dtros" wouldn't hurt either...
[...]
How is the situation for other libraries, say e.g. pthreads? Are they allowed to run after main ended?
Main (initial) *thread* is just a thread, nothing special. Main *function* is special. Return from main is just like calling exit() -- it evaporates all threads without any thread cleanup. OTOH, mere termination of main/initial thread (by means of pthread_exit() or thread cancellation), has no effect with respect to other threads.
This sounds interesting to me. It is really possible to use pthread_exit() to exit the main thread?
Yes. You can also cancel it. pthread_exit(PTHREAD_CANCELED); is a shortcut for pthread_cancel(pthread_self()); pthread_testcancel(); See also http://www.codesourcery.com/archives/c++-pthreads/msg00005.html
And what happens then?
Main/initial thread terminates.
Are the global destuctors called?
Only if main/initial is the last thread.
Or are they held off until the last thread exited?
Yes. regards, alexander.
participants (2)
-
Alexander Terekhov
-
Roland