This is the mail archive of the
mailing list for the glibc project.
Re: TSD destructors not being called for initial thread
- From: Kaz Kylheku <kaz at ashi dot footprints dot net>
- To: Boris Kolpackov <boris at kolpackov dot net>
- Cc: libc-alpha at sources dot redhat dot com
- Date: Wed, 31 Mar 2004 10:34:32 -0800 (PST)
- Subject: Re: TSD destructors not being called for initial thread
On Wed, 31 Mar 2004, Boris Kolpackov wrote:
> Date: Wed, 31 Mar 2004 10:20:22 -0600
> From: Boris Kolpackov <email@example.com>
> To: Kaz Kylheku <firstname.lastname@example.org>
> Cc: email@example.com
> Subject: Re: TSD destructors not being called for initial thread
> Hi Kaz,
> > TSD cleanup for the main thread only makes sense if it calls
> > pthread_exit or otherwise terminates in a way that does not take down
> > the whole process.
> > It therefore doesn't make sense to do it as a part of the global
> > process cleanup.
> > ...
> > TSD cleanup is designed to prevent resource leaks in programs that
> > create and terminate lots of threads; it's not for cleaning up process
> > resources. If TSD contains a reference to some resource that has to be
> > cleaned up no matter how the process terminates (and is not cleaned up
> > automatically by the system), then TSD destructors are not the
> > appropriate mechanism to arrange that cleanup.
> What you said makes sense, but the spec (SUS) says
> "At thread exit, if a key value has a non-NULL destructor pointer,
> and the thread has a non-NULL value associated with that key, the
> value of the key is set to NULL, and then the function pointed to
> is called with the previously associated value as its sole argument."
> Also it never says that this does not apply to the initial thread.
That is true. However, there are no guarantees about how soon the
cleanup happens. If the cleanup is delayed until the process
terminates, then it's okay for it not to happen.
The spec doesn't say that the first destructor must be called within X
milliseconds of the pthread_exit().
What you do know is that the destructors are called in the context of
the thread that is shutting down, so that by the time a pthread_join()
succeeds on that thread, the destructors must be done.
If you can join the thread, and the destructors have not been called,
then you have a problem, because certain events did not happen
in their implied causal order.
> Just in case one argues that the spec is brain-damaged, etc. But then
The one brain-damaged aspect of TSD is that the owning thread executes
the destructors (and in the course of doing so, can introduce new TSD!). A
better design is to allow TSD to outlive its thread, and be reclaimed by
some other thread. Then you don't run into the stupid problem of having
to iterate because the destructors associate new data with keys. You can
also collect TSD from more than one dead thread in one pass; there is
room for optimization. For instance you can let the TSD garbage build
up and then iterate over the slots of multiple threads in parallel to
call the same destructor multiple times in a row, resulting in fewer
instruction cache misses, page faults and context switches.