1 /* __pthread_destory_specific.  Hurd version.
2    Copyright (C) 2002-2021 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library;  if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <pthread.h>
20 #include <stdlib.h>
21 
22 #include <pt-internal.h>
23 
24 void
__pthread_destroy_specific(struct __pthread * thread)25 __pthread_destroy_specific (struct __pthread *thread)
26 {
27   int i;
28   int seen_one;
29 
30   /* Check if there is any thread specific data.  */
31   if (thread->thread_specifics == NULL)
32     return;
33 
34   __pthread_key_lock_ready ();
35 
36   /* Iterate and call the destructors on any thread specific data.  */
37   for (;;)
38     {
39       seen_one = 0;
40 
41       __pthread_mutex_lock (&__pthread_key_lock);
42 
43       for (i = 0; i < __pthread_key_count && i < thread->thread_specifics_size;
44 	   i++)
45 	{
46 	  void *value;
47 
48 	  if (__pthread_key_destructors[i] == PTHREAD_KEY_INVALID)
49 	    continue;
50 
51 	  value = thread->thread_specifics[i];
52 	  if (value != NULL)
53 	    {
54 	      thread->thread_specifics[i] = 0;
55 
56 	      if (__pthread_key_destructors[i])
57 		{
58 		  seen_one = 1;
59 		  __pthread_key_destructors[i] (value);
60 		}
61 	    }
62 	}
63 
64       __pthread_mutex_unlock (&__pthread_key_lock);
65 
66       if (!seen_one)
67 	break;
68 
69       /* This may take a very long time.  Let those blocking on
70          pthread_key_create or pthread_key_delete make progress.  */
71       __sched_yield ();
72     }
73 
74   free (thread->thread_specifics);
75   thread->thread_specifics = 0;
76   thread->thread_specifics_size = 0;
77 }
78