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

Side by Side Diff: mozilla/security/nss/lib/base/error.c

Issue 14249009: Change the NSS and NSPR source tree to the new directory structure to be (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « mozilla/security/nss/lib/base/baset.h ('k') | mozilla/security/nss/lib/base/errorval.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 #ifdef DEBUG
6 static const char CVS_ID[] = "@(#) $RCSfile: error.c,v $ $Revision: 1.10 $ $Date : 2012/04/25 14:49:26 $";
7 #endif /* DEBUG */
8
9 /*
10 * error.c
11 *
12 * This file contains the code implementing the per-thread error
13 * stacks upon which most NSS routines report their errors.
14 */
15
16 #ifndef BASE_H
17 #include "base.h"
18 #endif /* BASE_H */
19 #include <limits.h> /* for UINT_MAX */
20 #include <string.h> /* for memmove */
21
22 #define NSS_MAX_ERROR_STACK_COUNT 16 /* error codes */
23
24 /*
25 * The stack itself has a header, and a sequence of integers.
26 * The header records the amount of space (as measured in stack
27 * slots) already allocated for the stack, and the count of the
28 * number of records currently being used.
29 */
30
31 struct stack_header_str {
32 PRUint16 space;
33 PRUint16 count;
34 };
35
36 struct error_stack_str {
37 struct stack_header_str header;
38 PRInt32 stack[1];
39 };
40 typedef struct error_stack_str error_stack;
41
42 /*
43 * error_stack_index
44 *
45 * Thread-private data must be indexed. This is that index.
46 * See PR_NewThreadPrivateIndex for more information.
47 *
48 * Thread-private data indexes are in the range [0, 127].
49 */
50
51 #define INVALID_TPD_INDEX UINT_MAX
52 static PRUintn error_stack_index = INVALID_TPD_INDEX;
53
54 /*
55 * call_once
56 *
57 * The thread-private index must be obtained (once!) at runtime.
58 * This block is used for that one-time call.
59 */
60
61 static PRCallOnceType error_call_once;
62
63 /*
64 * error_once_function
65 *
66 * This is the once-called callback.
67 */
68 static PRStatus
69 error_once_function ( void)
70 {
71 return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free);
72 }
73
74 /*
75 * error_get_my_stack
76 *
77 * This routine returns the calling thread's error stack, creating
78 * it if necessary. It may return NULL upon error, which implicitly
79 * means that it ran out of memory.
80 */
81
82 static error_stack *
83 error_get_my_stack ( void)
84 {
85 PRStatus st;
86 error_stack *rv;
87 PRUintn new_size;
88 PRUint32 new_bytes;
89 error_stack *new_stack;
90
91 if( INVALID_TPD_INDEX == error_stack_index ) {
92 st = PR_CallOnce(&error_call_once, error_once_function);
93 if( PR_SUCCESS != st ) {
94 return (error_stack *)NULL;
95 }
96 }
97
98 rv = (error_stack *)PR_GetThreadPrivate(error_stack_index);
99 if( (error_stack *)NULL == rv ) {
100 /* Doesn't exist; create one */
101 new_size = 16;
102 } else if( rv->header.count == rv->header.space &&
103 rv->header.count < NSS_MAX_ERROR_STACK_COUNT ) {
104 /* Too small, expand it */
105 new_size = PR_MIN( rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT);
106 } else {
107 /* Okay, return it */
108 return rv;
109 }
110
111 new_bytes = (new_size * sizeof(PRInt32)) + sizeof(error_stack);
112 /* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */
113 new_stack = PR_Calloc(1, new_bytes);
114
115 if( (error_stack *)NULL != new_stack ) {
116 if( (error_stack *)NULL != rv ) {
117 (void)nsslibc_memcpy(new_stack,rv,rv->header.space);
118 }
119 new_stack->header.space = new_size;
120 }
121
122 /* Set the value, whether or not the allocation worked */
123 PR_SetThreadPrivate(error_stack_index, new_stack);
124 return new_stack;
125 }
126
127 /*
128 * The error stack
129 *
130 * The public methods relating to the error stack are:
131 *
132 * NSS_GetError
133 * NSS_GetErrorStack
134 *
135 * The nonpublic methods relating to the error stack are:
136 *
137 * nss_SetError
138 * nss_ClearErrorStack
139 *
140 */
141
142 /*
143 * NSS_GetError
144 *
145 * This routine returns the highest-level (most general) error set
146 * by the most recent NSS library routine called by the same thread
147 * calling this routine.
148 *
149 * This routine cannot fail. However, it may return zero, which
150 * indicates that the previous NSS library call did not set an error.
151 *
152 * Return value:
153 * 0 if no error has been set
154 * A nonzero error number
155 */
156
157 NSS_IMPLEMENT PRInt32
158 NSS_GetError ( void)
159 {
160 error_stack *es = error_get_my_stack();
161
162 if( (error_stack *)NULL == es ) {
163 return NSS_ERROR_NO_MEMORY; /* Good guess! */
164 }
165
166 if( 0 == es->header.count ) {
167 return 0;
168 }
169
170 return es->stack[ es->header.count-1 ];
171 }
172
173 /*
174 * NSS_GetErrorStack
175 *
176 * This routine returns a pointer to an array of integers, containing
177 * the entire sequence or "stack" of errors set by the most recent NSS
178 * library routine called by the same thread calling this routine.
179 * NOTE: the caller DOES NOT OWN the memory pointed to by the return
180 * value. The pointer will remain valid until the calling thread
181 * calls another NSS routine. The lowest-level (most specific) error
182 * is first in the array, and the highest-level is last. The array is
183 * zero-terminated. This routine may return NULL upon error; this
184 * indicates a low-memory situation.
185 *
186 * Return value:
187 * NULL upon error, which is an implied NSS_ERROR_NO_MEMORY
188 * A NON-caller-owned pointer to an array of integers
189 */
190
191 NSS_IMPLEMENT PRInt32 *
192 NSS_GetErrorStack ( void)
193 {
194 error_stack *es = error_get_my_stack();
195
196 if( (error_stack *)NULL == es ) {
197 return (PRInt32 *)NULL;
198 }
199
200 /* Make sure it's terminated */
201 es->stack[ es->header.count ] = 0;
202
203 return es->stack;
204 }
205
206 /*
207 * nss_SetError
208 *
209 * This routine places a new error code on the top of the calling
210 * thread's error stack. Calling this routine wiht an error code
211 * of zero will clear the error stack.
212 */
213
214 NSS_IMPLEMENT void
215 nss_SetError ( PRUint32 error)
216 {
217 error_stack *es;
218
219 if( 0 == error ) {
220 nss_ClearErrorStack();
221 return;
222 }
223
224 es = error_get_my_stack();
225 if( (error_stack *)NULL == es ) {
226 /* Oh, well. */
227 return;
228 }
229
230 if (es->header.count < es->header.space) {
231 es->stack[ es->header.count++ ] = error;
232 } else {
233 memmove(es->stack, es->stack + 1,
234 (es->header.space - 1) * (sizeof es->stack[0]));
235 es->stack[ es->header.space - 1 ] = error;
236 }
237 return;
238 }
239
240 /*
241 * nss_ClearErrorStack
242 *
243 * This routine clears the calling thread's error stack.
244 */
245
246 NSS_IMPLEMENT void
247 nss_ClearErrorStack ( void)
248 {
249 error_stack *es = error_get_my_stack();
250 if( (error_stack *)NULL == es ) {
251 /* Oh, well. */
252 return;
253 }
254
255 es->header.count = 0;
256 es->stack[0] = 0;
257 return;
258 }
259
260 /*
261 * nss_DestroyErrorStack
262 *
263 * This routine frees the calling thread's error stack.
264 */
265
266 NSS_IMPLEMENT void
267 nss_DestroyErrorStack ( void)
268 {
269 if( INVALID_TPD_INDEX != error_stack_index ) {
270 PR_SetThreadPrivate(error_stack_index, NULL);
271 }
272 return;
273 }
OLDNEW
« no previous file with comments | « mozilla/security/nss/lib/base/baset.h ('k') | mozilla/security/nss/lib/base/errorval.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698