1 /*
2 * The contents of this file are subject to the Mozilla Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/MPL/
6 *
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
11 *
12 * The Original Code is the Netscape Portable Runtime library.
13 *
14 * The Initial Developer of the Original Code is Netscape
15 * Communications Corporation. Portions created by Netscape are
16 * Copyright (C) 1994-2000 Netscape Communications Corporation. All
17 * Rights Reserved.
18 *
19 * Contributor(s): Silicon Graphics, Inc.
20 *
21 * Portions created by SGI are Copyright (C) 2000-2001 Silicon
22 * Graphics, Inc. All Rights Reserved.
23 *
24 * Alternatively, the contents of this file may be used under the
25 * terms of the GNU General Public License Version 2 or later (the
26 * "GPL"), in which case the provisions of the GPL are applicable
27 * instead of those above. If you wish to allow use of your
28 * version of this file only under the terms of the GPL and not to
29 * allow others to use your version of this file under the MPL,
30 * indicate your decision by deleting the provisions above and
31 * replace them with the notice and other provisions required by
32 * the GPL. If you do not delete the provisions above, a recipient
33 * may use your version of this file under either the MPL or the
34 * GPL.
35 */
36
37 /*
38 * This file is derived directly from Netscape Communications Corporation,
39 * and consists of extensive modifications made during the year(s) 1999-2000.
40 */
41
42 #include <stdlib.h>
43 #include <errno.h>
44 #include "common.h"
45
46
47 /*
48 * Destructor table for per-thread private data
49 */
50 static _st_destructor_t _st_destructors[ST_KEYS_MAX];
51 static int key_max = 0;
52
53
54 /*
55 * Return a key to be used for thread specific data
56 */
st_key_create(int * keyp,_st_destructor_t destructor)57 int st_key_create(int *keyp, _st_destructor_t destructor)
58 {
59 if (key_max >= ST_KEYS_MAX) {
60 errno = EAGAIN;
61 return -1;
62 }
63
64 *keyp = key_max++;
65 _st_destructors[*keyp] = destructor;
66
67 return 0;
68 }
69
70
st_key_getlimit(void)71 int st_key_getlimit(void)
72 {
73 return ST_KEYS_MAX;
74 }
75
76
st_thread_setspecific(int key,void * value)77 int st_thread_setspecific(int key, void *value)
78 {
79 _st_thread_t *me = _ST_CURRENT_THREAD();
80
81 if (key < 0 || key >= key_max) {
82 errno = EINVAL;
83 return -1;
84 }
85
86 if (value != me->private_data[key]) {
87 /* free up previously set non-NULL data value */
88 if (me->private_data[key] && _st_destructors[key]) {
89 (*_st_destructors[key])(me->private_data[key]);
90 }
91 me->private_data[key] = value;
92 }
93
94 return 0;
95 }
96
97
st_thread_getspecific(int key)98 void *st_thread_getspecific(int key)
99 {
100 if (key < 0 || key >= key_max)
101 return NULL;
102
103 return ((_ST_CURRENT_THREAD())->private_data[key]);
104 }
105
106
107 /*
108 * Free up all per-thread private data
109 */
_st_thread_cleanup(_st_thread_t * thread)110 void _st_thread_cleanup(_st_thread_t *thread)
111 {
112 int key;
113
114 for (key = 0; key < key_max; key++) {
115 if (thread->private_data[key] && _st_destructors[key]) {
116 (*_st_destructors[key])(thread->private_data[key]);
117 thread->private_data[key] = NULL;
118 }
119 }
120 }
121
122