1 /*
2  * pthread_key_delete.c
3  *
4  * Description:
5  * POSIX thread functions which implement thread-specific data (TSD).
6  *
7  * --------------------------------------------------------------------------
8  *
9  *      Pthreads-win32 - POSIX Threads Library for Win32
10  *      Copyright(C) 1998 John E. Bossom
11  *      Copyright(C) 1999,2005 Pthreads-win32 contributors
12  *
13  *      Contact Email: rpj@callisto.canberra.edu.au
14  *
15  *      The current list of contributors is contained
16  *      in the file CONTRIBUTORS included with the source
17  *      code distribution. The list can also be seen at the
18  *      following World Wide Web location:
19  *      http://sources.redhat.com/pthreads-win32/contributors.html
20  *
21  *      This library is free software; you can redistribute it and/or
22  *      modify it under the terms of the GNU Lesser General Public
23  *      License as published by the Free Software Foundation; either
24  *      version 2 of the License, or (at your option) any later version.
25  *
26  *      This library is distributed in the hope that it will be useful,
27  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
28  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29  *      Lesser General Public License for more details.
30  *
31  *      You should have received a copy of the GNU Lesser General Public
32  *      License along with this library in the file COPYING.LIB;
33  *      if not, write to the Free Software Foundation, Inc.,
34  *      51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
35  */
36 
37 #include "pthread.h"
38 #include "implement.h"
39 
40 
41 int
pthread_key_delete(pthread_key_t key)42 pthread_key_delete (pthread_key_t key)
43      /*
44       * ------------------------------------------------------
45       * DOCPUBLIC
46       *      This function deletes a thread-specific data key. This
47       *      does not change the value of the thread specific data key
48       *      for any thread and does not run the key's destructor
49       *      in any thread so it should be used with caution.
50       *
51       * PARAMETERS
52       *      key
53       *              pointer to an instance of pthread_key_t
54       *
55       *
56       * DESCRIPTION
57       *      This function deletes a thread-specific data key. This
58       *      does not change the value of the thread specific data key
59       *      for any thread and does not run the key's destructor
60       *      in any thread so it should be used with caution.
61       *
62       * RESULTS
63       *              0               successfully deleted the key,
64       *              EINVAL          key is invalid,
65       *
66       * ------------------------------------------------------
67       */
68 {
69   ptw32_mcs_local_node_t keyLock;
70   int result = 0;
71 
72   if (key != NULL)
73     {
74       if (key->threads != NULL && key->destructor != NULL)
75 	{
76 	  ThreadKeyAssoc *assoc;
77 	  ptw32_mcs_lock_acquire (&(key->keyLock), &keyLock);
78 	  /*
79 	   * Run through all Thread<-->Key associations
80 	   * for this key.
81 	   *
82 	   * While we hold at least one of the locks guarding
83 	   * the assoc, we know that the assoc pointed to by
84 	   * key->threads is valid.
85 	   */
86 	  while ((assoc = (ThreadKeyAssoc *) key->threads) != NULL)
87 	    {
88               ptw32_mcs_local_node_t threadLock;
89 	      ptw32_thread_t * thread = assoc->thread;
90 
91 	      if (assoc == NULL)
92 		{
93 		  /* Finished */
94 		  break;
95 		}
96 
97 	      ptw32_mcs_lock_acquire (&(thread->threadLock), &threadLock);
98 	      /*
99 	       * Since we are starting at the head of the key's threads
100 	       * chain, this will also point key->threads at the next assoc.
101 	       * While we hold key->keyLock, no other thread can insert
102 	       * a new assoc via pthread_setspecific.
103 	       */
104 	      ptw32_tkAssocDestroy (assoc);
105 	      ptw32_mcs_lock_release (&threadLock);
106 	      ptw32_mcs_lock_release (&keyLock);
107 	    }
108 	}
109 
110       TlsFree (key->key);
111       if (key->destructor != NULL)
112 	{
113 	  /* A thread could be holding the keyLock */
114 	  ptw32_mcs_lock_acquire (&(key->keyLock), &keyLock);
115 	  ptw32_mcs_lock_release (&keyLock);
116 	}
117 
118 #if defined( _DEBUG )
119       memset ((char *) key, 0, sizeof (*key));
120 #endif
121       free (key);
122     }
123 
124   return (result);
125 }
126