Cleanup of pthread_key thread-specific data
Cleanup of pthread_key thread-specific data
- Subject: Cleanup of pthread_key thread-specific data
- From: Sam Vaughan <email@hidden>
- Date: Mon, 24 Sep 2007 12:16:52 +1000
I was concerned to read the following paragraph in the
pthread_key_create man page this morning:
If, after all the destructors have been called for all non-NULL
values
with associated destructors, there are still some non-NULL values
with
associated destructors, then the process is repeated. If, after
at least
[PTHREAD_DESTRUCTOR_ITERATIONS] iterations of destructor calls for
out-
standing non-NULL values, there are still some non-NULL values
with asso-
ciated destructors, the implementation stops calling destructors.
The reason for my concern was that I have code that creates a key for
per-thread buffers using pthread_key_create(&key, free). The idea is
that the destructor for key values is the standard libc free()
function. Each thread calls pthread_getspecific with the key to get
their buffer. If it's NULL, as it will be the first time they call
it, they allocate a new buffer and store its address with
pthread_setspecific. They then rest assured that the buffer will be
freed automatically when they terminate.
If my interpretation of the man page is correct, my code would call
free() PTHREAD_DESTRUCTOR_ITERATIONS times in a row for each thread's
buffer pointer when the threads are destroyed. This would obviously
be bad. To fix it I'd need to have my own destructor function that
knows the key and calls pthread_setspecific to clear the thread's key
value after calling free() itself.
I wrote a little program to see what behaviour really occurs on
10.4.10 and found that the key destructor is actually only called
once, even if it doesn't clear the key value itself.
I then had a look in the libc source and saw that the thread-specific
data cleanup function explicitly clears the key value just before
calling the destructor. See _pthread_tsd_cleanup() in pthread_tsd.c,
right down the bottom. The outer for() loop is actually completely
redundant.
So I'm now wondering if I should fix (and complicate) my code to
match the man page in case libc gets fixed, or leave it alone and
perhaps submit a bug report. Any suggestions?
Thanks,
Sam
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden