2 * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
5 * Permission to use, copy, modify, and distribute this software and
6 * its documentation for any purpose and without fee is hereby granted,
7 * provided that the above copyright notice appears in all copies and
8 * that both the copyright notice and this permission notice appear in
9 * supporting documentation.
11 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
12 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13 * FOR A PARTICULAR PURPOSE.
15 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
16 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
18 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
19 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 * POSIX Pthread Library
28 * Thread Specific Data support
31 #include "pthread_internals.h"
35 int created
; /* Set TRUE if 'create_key' used this slot */
36 void (*destructor
)(void *);
37 } _pthread_keys
[_POSIX_THREAD_KEYS_MAX
];
38 static pthread_lock_t tds_lock
= LOCK_INITIALIZER
;
41 * Create a new key for thread specific data
44 pthread_key_create(pthread_key_t
*key
,
45 void (*destructor
)(void *))
49 res
= ENOMEM
; /* No 'free' keys */
50 for (i
= 0; i
< _POSIX_THREAD_KEYS_MAX
; i
++)
52 if (_pthread_keys
[i
].created
== FALSE
)
54 _pthread_keys
[i
].created
= TRUE
;
55 _pthread_keys
[i
].destructor
= destructor
;
66 * Destroy a thread specific data key
69 pthread_key_delete(pthread_key_t key
)
73 if ((key
>= 1) && (key
<= _POSIX_THREAD_KEYS_MAX
))
75 if (_pthread_keys
[key
-1].created
)
77 _pthread_keys
[key
-1].created
= FALSE
;
92 * Set the thread private value for a given key.
93 * We do not take the spinlock for this or pthread_getspecific.
94 * The assignment to self->tsd[] is thread-safe because we never
95 * refer to the tsd[] of a thread other than pthread_self().
96 * The reference to _pthread_keys[...].created could race with a
97 * pthread_key_delete() but in this case the behaviour is allowed
101 pthread_setspecific(pthread_key_t key
,
106 if ((key
>= 1) && (key
<= _POSIX_THREAD_KEYS_MAX
))
108 if (_pthread_keys
[key
-1].created
)
110 self
= pthread_self();
111 self
->tsd
[key
-1] = (void *) value
;
125 * Fetch the thread private value for a given key.
126 * This is potentially a very heavily-used operation so we do only
127 * a minimum of checks.
130 pthread_getspecific(pthread_key_t key
)
134 if ((key
>= 1) && (key
<= _POSIX_THREAD_KEYS_MAX
))
136 self
= pthread_self();
137 res
= self
->tsd
[key
-1];
139 { /* Invalid key - no error, just NULL */
146 * Clean up thread specific data as thread 'dies'
149 _pthread_tsd_cleanup(pthread_t self
)
153 for (j
= 0; j
< PTHREAD_DESTRUCTOR_ITERATIONS
; j
++)
155 for (i
= 0; i
< _POSIX_THREAD_KEYS_MAX
; i
++)
157 if (_pthread_keys
[i
].created
&& (param
= self
->tsd
[i
]))
159 self
->tsd
[i
] = (void *)NULL
;
160 if (_pthread_keys
[i
].destructor
)
162 (_pthread_keys
[i
].destructor
)(param
);