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

Side by Side Diff: nss/lib/base/tracker.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 | « nss/lib/base/nssutf8.c ('k') | nss/lib/certdb/alg1485.c » ('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 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 /*
6 * tracker.c
7 *
8 * This file contains the code used by the pointer-tracking calls used
9 * in the debug builds to catch bad pointers. The entire contents are
10 * only available in debug builds (both internal and external builds).
11 */
12
13 #ifndef BASE_H
14 #include "base.h"
15 #endif /* BASE_H */
16
17 #ifdef DEBUG
18 /*
19 * identity_hash
20 *
21 * This static callback is a PLHashFunction as defined in plhash.h
22 * It merely returns the value of the object pointer as its hash.
23 * There are no possible errors.
24 */
25
26 static PLHashNumber PR_CALLBACK
27 identity_hash(const void *key)
28 {
29 return (PLHashNumber)((char *)key - (char *)NULL);
30 }
31
32 /*
33 * trackerOnceFunc
34 *
35 * This function is called once, using the nssCallOnce function above.
36 * It creates a new pointer tracker object; initialising its hash
37 * table and protective lock.
38 */
39
40 static PRStatus
41 trackerOnceFunc(void *arg)
42 {
43 nssPointerTracker *tracker = (nssPointerTracker *)arg;
44
45 tracker->lock = PZ_NewLock(nssILockOther);
46 if ((PZLock *)NULL == tracker->lock) {
47 return PR_FAILURE;
48 }
49
50 tracker->table =
51 PL_NewHashTable(0, identity_hash, PL_CompareValues, PL_CompareValues,
52 (PLHashAllocOps *)NULL, (void *)NULL);
53 if ((PLHashTable *)NULL == tracker->table) {
54 PZ_DestroyLock(tracker->lock);
55 tracker->lock = (PZLock *)NULL;
56 return PR_FAILURE;
57 }
58
59 return PR_SUCCESS;
60 }
61
62 /*
63 * nssPointerTracker_initialize
64 *
65 * This method is only present in debug builds.
66 *
67 * This routine initializes an nssPointerTracker object. Note that
68 * the object must have been declared *static* to guarantee that it
69 * is in a zeroed state initially. This routine is idempotent, and
70 * may even be safely called by multiple threads simultaneously with
71 * the same argument. This routine returns a PRStatus value; if
72 * successful, it will return PR_SUCCESS. On failure it will set an
73 * error on the error stack and return PR_FAILURE.
74 *
75 * The error may be one of the following values:
76 * NSS_ERROR_NO_MEMORY
77 *
78 * Return value:
79 * PR_SUCCESS
80 * PR_FAILURE
81 */
82
83 NSS_IMPLEMENT PRStatus
84 nssPointerTracker_initialize(nssPointerTracker *tracker)
85 {
86 PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker);
87 if (PR_SUCCESS != rv) {
88 nss_SetError(NSS_ERROR_NO_MEMORY);
89 }
90
91 return rv;
92 }
93
94 #ifdef DONT_DESTROY_EMPTY_TABLES
95 /* See same #ifdef below */
96 /*
97 * count_entries
98 *
99 * This static routine is a PLHashEnumerator, as defined in plhash.h.
100 * It merely causes the enumeration function to count the number of
101 * entries.
102 */
103
104 static PRIntn PR_CALLBACK
105 count_entries(PLHashEntry *he, PRIntn index, void *arg)
106 {
107 return HT_ENUMERATE_NEXT;
108 }
109 #endif /* DONT_DESTROY_EMPTY_TABLES */
110
111 /*
112 * zero_once
113 *
114 * This is a guaranteed zeroed once block. It's used to help clear
115 * the tracker.
116 */
117
118 static const PRCallOnceType zero_once;
119
120 /*
121 * nssPointerTracker_finalize
122 *
123 * This method is only present in debug builds.
124 *
125 * This routine returns the nssPointerTracker object to the pre-
126 * initialized state, releasing all resources used by the object.
127 * It will *NOT* destroy the objects being tracked by the pointer
128 * (should any remain), and therefore cannot be used to "sweep up"
129 * remaining objects. This routine returns a PRStatus value; if
130 * successful, it will return PR_SUCCES. On failure it will set an
131 * error on the error stack and return PR_FAILURE. If any objects
132 * remain in the tracker when it is finalized, that will be treated
133 * as an error.
134 *
135 * The error may be one of the following values:
136 * NSS_ERROR_INVALID_POINTER
137 * NSS_ERROR_TRACKER_NOT_INITIALIZED
138 * NSS_ERROR_TRACKER_NOT_EMPTY
139 *
140 * Return value:
141 * PR_SUCCESS
142 * PR_FAILURE
143 */
144
145 NSS_IMPLEMENT PRStatus
146 nssPointerTracker_finalize(nssPointerTracker *tracker)
147 {
148 PZLock *lock;
149
150 if ((nssPointerTracker *)NULL == tracker) {
151 nss_SetError(NSS_ERROR_INVALID_POINTER);
152 return PR_FAILURE;
153 }
154
155 if ((PZLock *)NULL == tracker->lock) {
156 nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
157 return PR_FAILURE;
158 }
159
160 lock = tracker->lock;
161 PZ_Lock(lock);
162
163 if ((PLHashTable *)NULL == tracker->table) {
164 PZ_Unlock(lock);
165 nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
166 return PR_FAILURE;
167 }
168
169 #ifdef DONT_DESTROY_EMPTY_TABLES
170 /*
171 * I changed my mind; I think we don't want this after all.
172 * Comments?
173 */
174 count = PL_HashTableEnumerateEntries(tracker->table, count_entries,
175 (void *)NULL);
176
177 if (0 != count) {
178 PZ_Unlock(lock);
179 nss_SetError(NSS_ERROR_TRACKER_NOT_EMPTY);
180 return PR_FAILURE;
181 }
182 #endif /* DONT_DESTROY_EMPTY_TABLES */
183
184 PL_HashTableDestroy(tracker->table);
185 /* memset(tracker, 0, sizeof(nssPointerTracker)); */
186 tracker->once = zero_once;
187 tracker->lock = (PZLock *)NULL;
188 tracker->table = (PLHashTable *)NULL;
189
190 PZ_Unlock(lock);
191 PZ_DestroyLock(lock);
192
193 return PR_SUCCESS;
194 }
195
196 /*
197 * nssPointerTracker_add
198 *
199 * This method is only present in debug builds.
200 *
201 * This routine adds the specified pointer to the nssPointerTracker
202 * object. It should be called in constructor objects to register
203 * new valid objects. The nssPointerTracker is threadsafe, but this
204 * call is not idempotent. This routine returns a PRStatus value;
205 * if successful it will return PR_SUCCESS. On failure it will set
206 * an error on the error stack and return PR_FAILURE.
207 *
208 * The error may be one of the following values:
209 * NSS_ERROR_INVALID_POINTER
210 * NSS_ERROR_NO_MEMORY
211 * NSS_ERROR_TRACKER_NOT_INITIALIZED
212 * NSS_ERROR_DUPLICATE_POINTER
213 *
214 * Return value:
215 * PR_SUCCESS
216 * PR_FAILURE
217 */
218
219 NSS_IMPLEMENT PRStatus
220 nssPointerTracker_add(nssPointerTracker *tracker, const void *pointer)
221 {
222 void *check;
223 PLHashEntry *entry;
224
225 if ((nssPointerTracker *)NULL == tracker) {
226 nss_SetError(NSS_ERROR_INVALID_POINTER);
227 return PR_FAILURE;
228 }
229
230 if ((PZLock *)NULL == tracker->lock) {
231 nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
232 return PR_FAILURE;
233 }
234
235 PZ_Lock(tracker->lock);
236
237 if ((PLHashTable *)NULL == tracker->table) {
238 PZ_Unlock(tracker->lock);
239 nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
240 return PR_FAILURE;
241 }
242
243 check = PL_HashTableLookup(tracker->table, pointer);
244 if ((void *)NULL != check) {
245 PZ_Unlock(tracker->lock);
246 nss_SetError(NSS_ERROR_DUPLICATE_POINTER);
247 return PR_FAILURE;
248 }
249
250 entry = PL_HashTableAdd(tracker->table, pointer, (void *)pointer);
251
252 PZ_Unlock(tracker->lock);
253
254 if ((PLHashEntry *)NULL == entry) {
255 nss_SetError(NSS_ERROR_NO_MEMORY);
256 return PR_FAILURE;
257 }
258
259 return PR_SUCCESS;
260 }
261
262 /*
263 * nssPointerTracker_remove
264 *
265 * This method is only present in debug builds.
266 *
267 * This routine removes the specified pointer from the
268 * nssPointerTracker object. It does not call any destructor for the
269 * object; rather, this should be called from the object's destructor.
270 * The nssPointerTracker is threadsafe, but this call is not
271 * idempotent. This routine returns a PRStatus value; if successful
272 * it will return PR_SUCCESS. On failure it will set an error on the
273 * error stack and return PR_FAILURE.
274 *
275 * The error may be one of the following values:
276 * NSS_ERROR_INVALID_POINTER
277 * NSS_ERROR_TRACKER_NOT_INITIALIZED
278 * NSS_ERROR_POINTER_NOT_REGISTERED
279 *
280 * Return value:
281 * PR_SUCCESS
282 * PR_FAILURE
283 */
284
285 NSS_IMPLEMENT PRStatus
286 nssPointerTracker_remove(nssPointerTracker *tracker, const void *pointer)
287 {
288 PRBool registered;
289
290 if ((nssPointerTracker *)NULL == tracker) {
291 nss_SetError(NSS_ERROR_INVALID_POINTER);
292 return PR_FAILURE;
293 }
294
295 if ((PZLock *)NULL == tracker->lock) {
296 nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
297 return PR_FAILURE;
298 }
299
300 PZ_Lock(tracker->lock);
301
302 if ((PLHashTable *)NULL == tracker->table) {
303 PZ_Unlock(tracker->lock);
304 nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
305 return PR_FAILURE;
306 }
307
308 registered = PL_HashTableRemove(tracker->table, pointer);
309 PZ_Unlock(tracker->lock);
310
311 if (!registered) {
312 nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
313 return PR_FAILURE;
314 }
315
316 return PR_SUCCESS;
317 }
318
319 /*
320 * nssPointerTracker_verify
321 *
322 * This method is only present in debug builds.
323 *
324 * This routine verifies that the specified pointer has been registered
325 * with the nssPointerTracker object. The nssPointerTracker object is
326 * threadsafe, and this call may be safely called from multiple threads
327 * simultaneously with the same arguments. This routine returns a
328 * PRStatus value; if the pointer is registered this will return
329 * PR_SUCCESS. Otherwise it will set an error on the error stack and
330 * return PR_FAILURE. Although the error is suitable for leaving on
331 * the stack, callers may wish to augment the information available by
332 * placing a more type-specific error on the stack.
333 *
334 * The error may be one of the following values:
335 * NSS_ERROR_INVALID_POINTER
336 * NSS_ERROR_TRACKER_NOT_INITIALIZED
337 * NSS_ERROR_POINTER_NOT_REGISTERED
338 *
339 * Return value:
340 * PR_SUCCESS
341 * PR_FAILRUE
342 */
343
344 NSS_IMPLEMENT PRStatus
345 nssPointerTracker_verify(nssPointerTracker *tracker, const void *pointer)
346 {
347 void *check;
348
349 if ((nssPointerTracker *)NULL == tracker) {
350 nss_SetError(NSS_ERROR_INVALID_POINTER);
351 return PR_FAILURE;
352 }
353
354 if ((PZLock *)NULL == tracker->lock) {
355 nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
356 return PR_FAILURE;
357 }
358
359 PZ_Lock(tracker->lock);
360
361 if ((PLHashTable *)NULL == tracker->table) {
362 PZ_Unlock(tracker->lock);
363 nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
364 return PR_FAILURE;
365 }
366
367 check = PL_HashTableLookup(tracker->table, pointer);
368 PZ_Unlock(tracker->lock);
369
370 if ((void *)NULL == check) {
371 nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
372 return PR_FAILURE;
373 }
374
375 return PR_SUCCESS;
376 }
377
378 #endif /* DEBUG */
OLDNEW
« no previous file with comments | « nss/lib/base/nssutf8.c ('k') | nss/lib/certdb/alg1485.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698