Re: Cleanup of pthread_key thread-specific data
Re: Cleanup of pthread_key thread-specific data
- Subject: Re: Cleanup of pthread_key thread-specific data
- From: Sam Vaughan <email@hidden>
- Date: Tue, 25 Sep 2007 10:30:49 +1000
On 25/09/2007, at 9:50 AM, Greg Parker wrote:
Sam Vaughan wrote:
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.
Don't panic. Your code is fine.
Comforting words to hitch-hiking pthread coders everywhere.
libc erases the thread-specific data before calling the destructor
once. This is the correct behavior. You don't have to erase it
yourself.
The outer destructor loop is to handle the case where a thread-
specific destructor itself sets some thread-specific value (perhaps
for a new key, or a non-NULL value for an existing key that's
already had its destructor called once). The next iteration of the
loop will destroy that new value. If the thread-specific
destructors are still inserting new thread-specific values after
PTHREAD_DESTRUCTOR_ITERATIONS then libc just gives up and kills the
thread, leaking whatever values are left.
For example: your key's destructor is called once. Then some other
destructor is called, and that destructor calls into your code.
Your code sees that your thread-specific value is now NULL, and
creates a new one. Next time through the destructor loop, your
key's destructor will be called again to free this second value.
Thanks for explaining this, Greg. After checking man pages and
source on OpenBSD and Linux as well as the POSIX document at The Open
Group I was happy to leave my code alone, but it did seem odd that so
much man page space was devoted to the edge case you described.
I think the man page should be explicit about the fact that the key's
value is cleared just before the destructor is called to avoid the
confusion. The Linux man page at <http://linux.die.net/man/3/
pthread_key_create> explicitly states that "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". The Open Group is
explicit as well: <http://www.opengroup.org/onlinepubs/000095399/
functions/pthread_key_create.html>.
I opened Radar bug #5502493 for this.
Thanks for your help!
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