Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: nspr/pr/src/threads/prtpd.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nspr/pr/src/threads/prsem.c ('k') | nss.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 /*
7 ** Thread Private Data
8 **
9 ** There is an aribitrary limit on the number of keys that will be allocated
10 ** by the runtime. It's largish, so it is intended to be a sanity check, not
11 ** an impediment.
12 **
13 ** There is a counter, initialized to zero and incremented every time a
14 ** client asks for a new key, that holds the high water mark for keys. All
15 ** threads logically have the same high water mark and are permitted to
16 ** ask for TPD up to that key value.
17 **
18 ** The vector to hold the TPD are allocated when PR_SetThreadPrivate() is
19 ** called. The size of the vector will be some value greater than or equal
20 ** to the current high water mark. Each thread has its own TPD length and
21 ** vector.
22 **
23 ** Threads that get private data for keys they have not set (or perhaps
24 ** don't even exist for that thread) get a NULL return. If the key is
25 ** beyond the high water mark, an error will be returned.
26 */
27
28 /*
29 ** As of this time, BeOS has its own TPD implementation. Integrating
30 ** this standard one is a TODO for anyone with a bit of spare time on
31 ** their hand. For now, we just #ifdef out this whole file and use
32 ** the routines in pr/src/btthreads/
33 */
34
35 #ifndef XP_BEOS
36
37 #include "primpl.h"
38
39 #include <string.h>
40
41 #if defined(WIN95)
42 /*
43 ** Some local variables report warnings on Win95 because the code paths
44 ** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
45 ** The pragma suppresses the warning.
46 **
47 */
48 #pragma warning(disable : 4101)
49 #endif
50
51 #define _PR_TPD_LIMIT 128 /* arbitary limit on the TPD slots */
52 static PRInt32 _pr_tpd_length = 0; /* current length of destructor vector * /
53 static PRInt32 _pr_tpd_highwater = 0; /* next TPD key to be assigned */
54 static PRThreadPrivateDTOR *_pr_tpd_destructors = NULL;
55 /* the destructors are associated with
56 the keys, therefore asserting that
57 the TPD key depicts the data's 'type ' */
58
59 /*
60 ** Initialize the thread private data manipulation
61 */
62 void _PR_InitTPD(void)
63 {
64 _pr_tpd_destructors = (PRThreadPrivateDTOR*)
65 PR_CALLOC(_PR_TPD_LIMIT * sizeof(PRThreadPrivateDTOR*));
66 PR_ASSERT(NULL != _pr_tpd_destructors);
67 _pr_tpd_length = _PR_TPD_LIMIT;
68 }
69
70 /*
71 ** Clean up the thread private data manipulation
72 */
73 void _PR_CleanupTPD(void)
74 {
75 } /* _PR_CleanupTPD */
76
77 /*
78 ** This routine returns a new index for per-thread-private data table.
79 ** The index is visible to all threads within a process. This index can
80 ** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines
81 ** to save and retrieve data associated with the index for a thread.
82 **
83 ** The index independently maintains specific values for each binding thread.
84 ** A thread can only get access to its own thread-specific-data.
85 **
86 ** Upon a new index return the value associated with the index for all threads
87 ** is NULL, and upon thread creation the value associated with all indices for
88 ** that thread is NULL.
89 **
90 ** "dtor" is the destructor function to invoke when the private
91 ** data is set or destroyed
92 **
93 ** Returns PR_FAILURE if the total number of indices will exceed the maximun
94 ** allowed.
95 */
96
97 PR_IMPLEMENT(PRStatus) PR_NewThreadPrivateIndex(
98 PRUintn *newIndex, PRThreadPrivateDTOR dtor)
99 {
100 PRStatus rv;
101 PRInt32 index;
102
103 if (!_pr_initialized) _PR_ImplicitInitialization();
104
105 PR_ASSERT(NULL != newIndex);
106 PR_ASSERT(NULL != _pr_tpd_destructors);
107
108 index = PR_ATOMIC_INCREMENT(&_pr_tpd_highwater) - 1; /* allocate index */
109 if (_PR_TPD_LIMIT <= index)
110 {
111 PR_SetError(PR_TPD_RANGE_ERROR, 0);
112 rv = PR_FAILURE; /* that's just wrong */
113 }
114 else
115 {
116 _pr_tpd_destructors[index] = dtor; /* record destructor @index */
117 *newIndex = (PRUintn)index; /* copy into client's location */
118 rv = PR_SUCCESS; /* that's okay */
119 }
120
121 return rv;
122 }
123
124 /*
125 ** Define some per-thread-private data.
126 ** "index" is an index into the per-thread private data table
127 ** "priv" is the per-thread-private data
128 **
129 ** If the per-thread private data table has a previously registered
130 ** destructor function and a non-NULL per-thread-private data value,
131 ** the destructor function is invoked.
132 **
133 ** This can return PR_FAILURE if index is invalid (ie., beyond the limit
134 ** on the TPD slots) or memory is insufficient to allocate an expanded
135 ** vector.
136 */
137
138 PR_IMPLEMENT(PRStatus) PR_SetThreadPrivate(PRUintn index, void *priv)
139 {
140 PRThread *self = PR_GetCurrentThread();
141
142 /*
143 ** To improve performance, we don't check if the index has been
144 ** allocated.
145 */
146 if (index >= _PR_TPD_LIMIT)
147 {
148 PR_SetError(PR_TPD_RANGE_ERROR, 0);
149 return PR_FAILURE;
150 }
151
152 PR_ASSERT(((NULL == self->privateData) && (0 == self->tpdLength))
153 || ((NULL != self->privateData) && (0 != self->tpdLength)));
154
155 /*
156 ** If this thread does not have a sufficient vector for the index
157 ** being set, go ahead and extend this vector now.
158 */
159 if ((NULL == self->privateData) || (self->tpdLength <= index))
160 {
161 void *extension = PR_CALLOC(_pr_tpd_length * sizeof(void*));
162 if (NULL == extension)
163 {
164 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
165 return PR_FAILURE;
166 }
167 if (self->privateData) {
168 (void)memcpy(
169 extension, self->privateData,
170 self->tpdLength * sizeof(void*));
171 PR_DELETE(self->privateData);
172 }
173 self->tpdLength = _pr_tpd_length;
174 self->privateData = (void**)extension;
175 }
176 /*
177 ** There wasn't much chance of having to call the destructor
178 ** unless the slot already existed.
179 */
180 else if (self->privateData[index] && _pr_tpd_destructors[index])
181 {
182 void *data = self->privateData[index];
183 self->privateData[index] = NULL;
184 (*_pr_tpd_destructors[index])(data);
185 }
186
187 PR_ASSERT(index < self->tpdLength);
188 self->privateData[index] = priv;
189
190 return PR_SUCCESS;
191 }
192
193 /*
194 ** Recover the per-thread-private data for the current thread. "index" is
195 ** the index into the per-thread private data table.
196 **
197 ** The returned value may be NULL which is indistinguishable from an error
198 ** condition.
199 **
200 */
201
202 PR_IMPLEMENT(void*) PR_GetThreadPrivate(PRUintn index)
203 {
204 PRThread *self = PR_GetCurrentThread();
205 void *tpd = ((NULL == self->privateData) || (index >= self->tpdLength)) ?
206 NULL : self->privateData[index];
207
208 return tpd;
209 }
210
211 /*
212 ** Destroy the thread's private data, if any exists. This is called at
213 ** thread termination time only. There should be no threading issues
214 ** since this is being called by the thread itself.
215 */
216 void _PR_DestroyThreadPrivate(PRThread* self)
217 {
218 #define _PR_TPD_DESTRUCTOR_ITERATIONS 4
219
220 if (NULL != self->privateData) /* we have some */
221 {
222 PRBool clean;
223 PRUint32 index;
224 PRInt32 passes = _PR_TPD_DESTRUCTOR_ITERATIONS;
225 PR_ASSERT(0 != self->tpdLength);
226 do
227 {
228 clean = PR_TRUE;
229 for (index = 0; index < self->tpdLength; ++index)
230 {
231 void *priv = self->privateData[index]; /* extract */
232 if (NULL != priv) /* we have data at this index */
233 {
234 if (NULL != _pr_tpd_destructors[index])
235 {
236 self->privateData[index] = NULL; /* precondition */
237 (*_pr_tpd_destructors[index])(priv); /* destroy */
238 clean = PR_FALSE; /* unknown side effects */
239 }
240 }
241 }
242 } while ((--passes > 0) && !clean); /* limit # of passes */
243 /*
244 ** We give up after a fixed number of passes. Any non-NULL
245 ** thread-private data value with a registered destructor
246 ** function is not destroyed.
247 */
248 memset(self->privateData, 0, self->tpdLength * sizeof(void*));
249 }
250 } /* _PR_DestroyThreadPrivate */
251
252 #endif /* !XP_BEOS */
OLDNEW
« no previous file with comments | « nspr/pr/src/threads/prsem.c ('k') | nss.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698