public inbox for pthreads-win32@sourceware.org
 help / color / mirror / Atom feed
* When is the pthread_key_create destructor called?
@ 2008-03-22 15:13 Brian Cole
  2008-03-23  1:51 ` Ross Johnson
  0 siblings, 1 reply; 2+ messages in thread
From: Brian Cole @ 2008-03-22 15:13 UTC (permalink / raw)
  To: pthreads-win32

Is it safe to assume that when a thread exits its destructor functions
for thread specific values have finished executing before the thread
can be joined?

For example, is the following free of race conditions?
static pthread_key_t key;

void dtor(void *val)
{
  // safely push the data pointed to by val into some global data structure
}

void *thread_func(void *)
{
  pthread_setspecific(key, //pointer to some data that will be pushed
into a global data structure on exit);
  pthread_exit(NULL); // What happens if I don't call this and let it
run off the end of the function?
}

int main()
{
  pthread_key_create(key, dtor);

  pthread_t thrd;
  pthread_create(&thrd, NULL, thread_func, NULL);

  void *ret;
  pthread_join(thrd, &ret);

  // safe to assume data that was in thread local storage is all in my
global data structure?
}

If this is not the case, would adding a pthread_key_delete achieve the
desired behavior? And further, how cross-platform is this behavior
seeing as I can't find it explicitly stated in any pthreads
documentation.

To further complicate the matter my threads are actually OpenMP
threads. Is it safe to assume they will properly clean up thread
specific data in the same semantic fashion?

Thanks,
Brian

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: When is the pthread_key_create destructor called?
  2008-03-22 15:13 When is the pthread_key_create destructor called? Brian Cole
@ 2008-03-23  1:51 ` Ross Johnson
  0 siblings, 0 replies; 2+ messages in thread
From: Ross Johnson @ 2008-03-23  1:51 UTC (permalink / raw)
  To: Brian Cole; +Cc: pthreads-win32

Brian,

Brian Cole wrote:
> Is it safe to assume that when a thread exits its destructor functions
> for thread specific values have finished executing before the thread
> can be joined?
>   
Yes, pthread_join() waits and continues only after all destructors have 
returned. As described by the manual page and the standard 
(http://www.opengroup.org/onlinepubs/009695399/functions/pthread_key_create.html), 
the library rechecks all keys and their values in case a specific 
destructor needs to be called again. A key will be checked at most 
PTHREAD_DESTRUCTOR_ITERATIONS  (= 4, IIRC) times and if the key value is 
not null by that time the key is forcibly deleted.

> For example, is the following free of race conditions?
> static pthread_key_t key;
>
> void dtor(void *val)
> {
>   // safely push the data pointed to by val into some global data structure
> }
>
> void *thread_func(void *)
> {
>   pthread_setspecific(key, //pointer to some data that will be pushed
> into a global data structure on exit);
>   pthread_exit(NULL); // What happens if I don't call this and let it
> run off the end of the function?
> }
>   
You can let your thread routine run off the end - pthread_exit() is is 
called implicitly in that case.
> int main()
> {
>   pthread_key_create(key, dtor);
>
>   pthread_t thrd;
>   pthread_create(&thrd, NULL, thread_func, NULL);
>
>   void *ret;
>   pthread_join(thrd, &ret);
>
>   // safe to assume data that was in thread local storage is all in my
> global data structure?
> }
>   
It is safe to assume your destructors have been called and returned.
> If this is not the case, would adding a pthread_key_delete achieve the
> desired behavior?
No, pthread_key_delete() removes the key for ALL threads, but does not 
call the destructor for ANY threads. If you think of TSD keys as a two 
dimensional array, with threads across and keys down and each cell as a 
TSD association between a key and a thread. Exiting a thread removes a 
column of TSD associations, deleting a key removes a row of TSD 
associations.
>  And further, how cross-platform is this behavior
> seeing as I can't find it explicitly stated in any pthreads
> documentation.
>   
This is Single Unix Specification (nee POSIX) behaviour. The manual 
pages for each of these routines pretty much reflects the standard 
descriptions. See, for example:-

http://www.opengroup.org/onlinepubs/009695399/toc.htm
(In the left frame, select the "System Interfaces" volume and then 
section 3 "System Interfaces")

Specifically:
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_key_create.html
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_exit.html
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_join.html
http://www.opengroup.org/onlinepubs/009695399/functions/pthread_key_delete.html

> To further complicate the matter my threads are actually OpenMP
> threads. Is it safe to assume they will properly clean up thread
> specific data in the same semantic fashion?
>   
I'm not familiar with OpenMP.
> Thanks,
> Brian
>   

Regards.
Ross

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-03-23  1:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-22 15:13 When is the pthread_key_create destructor called? Brian Cole
2008-03-23  1:51 ` Ross Johnson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).