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

Side by Side Diff: nspr/pr/src/io/prlayer.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/io/pripv6.c ('k') | nspr/pr/src/io/prlog.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 /* -*- 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 ** File: prlayer.c
8 ** Description: Routines for handling pushable protocol modules on sockets.
9 */
10
11 #include "primpl.h"
12 #include "prerror.h"
13 #include "prmem.h"
14 #include "prlock.h"
15 #include "prlog.h"
16 #include "prio.h"
17
18 #include <string.h> /* for memset() */
19 static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack);
20
21 void PR_CALLBACK pl_FDDestructor(PRFileDesc *fd)
22 {
23 PR_ASSERT(fd != NULL);
24 if (NULL != fd->lower) fd->lower->higher = fd->higher;
25 if (NULL != fd->higher) fd->higher->lower = fd->lower;
26 PR_DELETE(fd);
27 }
28
29 /*
30 ** Default methods that just call down to the next fd.
31 */
32 static PRStatus PR_CALLBACK pl_TopClose (PRFileDesc *fd)
33 {
34 PRFileDesc *top, *lower;
35 PRStatus rv;
36
37 PR_ASSERT(fd != NULL);
38 PR_ASSERT(fd->lower != NULL);
39 PR_ASSERT(fd->secret == NULL);
40 PR_ASSERT(fd->methods->file_type == PR_DESC_LAYERED);
41
42 if (PR_IO_LAYER_HEAD == fd->identity) {
43 /*
44 * new style stack; close all the layers, before deleting the
45 * stack head
46 */
47 rv = fd->lower->methods->close(fd->lower);
48 _PR_DestroyIOLayer(fd);
49 return rv;
50 } else if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) {
51 /*
52 * lower layers of new style stack
53 */
54 lower = fd->lower;
55 /*
56 * pop and cleanup current layer
57 */
58 top = PR_PopIOLayer(fd->higher, PR_TOP_IO_LAYER);
59 top->dtor(top);
60 /*
61 * then call lower layer
62 */
63 return (lower->methods->close(lower));
64 } else {
65 /* old style stack */
66 top = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
67 top->dtor(top);
68 return (fd->methods->close)(fd);
69 }
70 }
71
72 static PRInt32 PR_CALLBACK pl_DefRead (PRFileDesc *fd, void *buf, PRInt32 amount )
73 {
74 PR_ASSERT(fd != NULL);
75 PR_ASSERT(fd->lower != NULL);
76
77 return (fd->lower->methods->read)(fd->lower, buf, amount);
78 }
79
80 static PRInt32 PR_CALLBACK pl_DefWrite (
81 PRFileDesc *fd, const void *buf, PRInt32 amount)
82 {
83 PR_ASSERT(fd != NULL);
84 PR_ASSERT(fd->lower != NULL);
85
86 return (fd->lower->methods->write)(fd->lower, buf, amount);
87 }
88
89 static PRInt32 PR_CALLBACK pl_DefAvailable (PRFileDesc *fd)
90 {
91 PR_ASSERT(fd != NULL);
92 PR_ASSERT(fd->lower != NULL);
93
94 return (fd->lower->methods->available)(fd->lower);
95 }
96
97 static PRInt64 PR_CALLBACK pl_DefAvailable64 (PRFileDesc *fd)
98 {
99 PR_ASSERT(fd != NULL);
100 PR_ASSERT(fd->lower != NULL);
101
102 return (fd->lower->methods->available64)(fd->lower);
103 }
104
105 static PRStatus PR_CALLBACK pl_DefFsync (PRFileDesc *fd)
106 {
107 PR_ASSERT(fd != NULL);
108 PR_ASSERT(fd->lower != NULL);
109
110 return (fd->lower->methods->fsync)(fd->lower);
111 }
112
113 static PRInt32 PR_CALLBACK pl_DefSeek (
114 PRFileDesc *fd, PRInt32 offset, PRSeekWhence how)
115 {
116 PR_ASSERT(fd != NULL);
117 PR_ASSERT(fd->lower != NULL);
118
119 return (fd->lower->methods->seek)(fd->lower, offset, how);
120 }
121
122 static PRInt64 PR_CALLBACK pl_DefSeek64 (
123 PRFileDesc *fd, PRInt64 offset, PRSeekWhence how)
124 {
125 PR_ASSERT(fd != NULL);
126 PR_ASSERT(fd->lower != NULL);
127
128 return (fd->lower->methods->seek64)(fd->lower, offset, how);
129 }
130
131 static PRStatus PR_CALLBACK pl_DefFileInfo (PRFileDesc *fd, PRFileInfo *info)
132 {
133 PR_ASSERT(fd != NULL);
134 PR_ASSERT(fd->lower != NULL);
135
136 return (fd->lower->methods->fileInfo)(fd->lower, info);
137 }
138
139 static PRStatus PR_CALLBACK pl_DefFileInfo64 (PRFileDesc *fd, PRFileInfo64 *info )
140 {
141 PR_ASSERT(fd != NULL);
142 PR_ASSERT(fd->lower != NULL);
143
144 return (fd->lower->methods->fileInfo64)(fd->lower, info);
145 }
146
147 static PRInt32 PR_CALLBACK pl_DefWritev (PRFileDesc *fd, const PRIOVec *iov,
148 PRInt32 size, PRIntervalTime timeout)
149 {
150 PR_ASSERT(fd != NULL);
151 PR_ASSERT(fd->lower != NULL);
152
153 return (fd->lower->methods->writev)(fd->lower, iov, size, timeout);
154 }
155
156 static PRStatus PR_CALLBACK pl_DefConnect (
157 PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
158 {
159 PR_ASSERT(fd != NULL);
160 PR_ASSERT(fd->lower != NULL);
161
162 return (fd->lower->methods->connect)(fd->lower, addr, timeout);
163 }
164
165 static PRStatus PR_CALLBACK pl_DefConnectcontinue (
166 PRFileDesc *fd, PRInt16 out_flags)
167 {
168 PR_ASSERT(fd != NULL);
169 PR_ASSERT(fd->lower != NULL);
170
171 return (fd->lower->methods->connectcontinue)(fd->lower, out_flags);
172 }
173
174 static PRFileDesc* PR_CALLBACK pl_TopAccept (
175 PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
176 {
177 PRStatus rv;
178 PRFileDesc *newfd, *layer = fd;
179 PRFileDesc *newstack;
180 PRBool newstyle_stack = PR_FALSE;
181
182 PR_ASSERT(fd != NULL);
183 PR_ASSERT(fd->lower != NULL);
184
185 /* test for new style stack */
186 while (NULL != layer->higher)
187 layer = layer->higher;
188 newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FA LSE;
189 newstack = PR_NEW(PRFileDesc);
190 if (NULL == newstack)
191 {
192 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
193 return NULL;
194 }
195 *newstack = *fd; /* make a copy of the accepting layer */
196
197 newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout);
198 if (NULL == newfd)
199 {
200 PR_DELETE(newstack);
201 return NULL;
202 }
203
204 if (newstyle_stack) {
205 newstack->lower = newfd;
206 newfd->higher = newstack;
207 return newstack;
208 } else {
209 /* this PR_PushIOLayer call cannot fail */
210 rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
211 PR_ASSERT(PR_SUCCESS == rv);
212 return newfd; /* that's it */
213 }
214 }
215
216 static PRStatus PR_CALLBACK pl_DefBind (PRFileDesc *fd, const PRNetAddr *addr)
217 {
218 PR_ASSERT(fd != NULL);
219 PR_ASSERT(fd->lower != NULL);
220
221 return (fd->lower->methods->bind)(fd->lower, addr);
222 }
223
224 static PRStatus PR_CALLBACK pl_DefListen (PRFileDesc *fd, PRIntn backlog)
225 {
226 PR_ASSERT(fd != NULL);
227 PR_ASSERT(fd->lower != NULL);
228
229 return (fd->lower->methods->listen)(fd->lower, backlog);
230 }
231
232 static PRStatus PR_CALLBACK pl_DefShutdown (PRFileDesc *fd, PRIntn how)
233 {
234 PR_ASSERT(fd != NULL);
235 PR_ASSERT(fd->lower != NULL);
236
237 return (fd->lower->methods->shutdown)(fd->lower, how);
238 }
239
240 static PRInt32 PR_CALLBACK pl_DefRecv (
241 PRFileDesc *fd, void *buf, PRInt32 amount,
242 PRIntn flags, PRIntervalTime timeout)
243 {
244 PR_ASSERT(fd != NULL);
245 PR_ASSERT(fd->lower != NULL);
246
247 return (fd->lower->methods->recv)(
248 fd->lower, buf, amount, flags, timeout);
249 }
250
251 static PRInt32 PR_CALLBACK pl_DefSend (
252 PRFileDesc *fd, const void *buf,
253 PRInt32 amount, PRIntn flags, PRIntervalTime timeout)
254 {
255 PR_ASSERT(fd != NULL);
256 PR_ASSERT(fd->lower != NULL);
257
258 return (fd->lower->methods->send)(fd->lower, buf, amount, flags, timeout);
259 }
260
261 static PRInt32 PR_CALLBACK pl_DefRecvfrom (
262 PRFileDesc *fd, void *buf, PRInt32 amount,
263 PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
264 {
265 PR_ASSERT(fd != NULL);
266 PR_ASSERT(fd->lower != NULL);
267
268 return (fd->lower->methods->recvfrom)(
269 fd->lower, buf, amount, flags, addr, timeout);
270 }
271
272 static PRInt32 PR_CALLBACK pl_DefSendto (
273 PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
274 const PRNetAddr *addr, PRIntervalTime timeout)
275 {
276 PR_ASSERT(fd != NULL);
277 PR_ASSERT(fd->lower != NULL);
278
279 return (fd->lower->methods->sendto)(
280 fd->lower, buf, amount, flags, addr, timeout);
281 }
282
283 static PRInt16 PR_CALLBACK pl_DefPoll (
284 PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
285 {
286 PR_ASSERT(fd != NULL);
287 PR_ASSERT(fd->lower != NULL);
288
289 return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags);
290 }
291
292 static PRInt32 PR_CALLBACK pl_DefAcceptread (
293 PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, void *buf,
294 PRInt32 amount, PRIntervalTime t)
295 {
296 PRInt32 nbytes;
297 PRStatus rv;
298 PRFileDesc *newstack;
299 PRFileDesc *layer = sd;
300 PRBool newstyle_stack = PR_FALSE;
301
302 PR_ASSERT(sd != NULL);
303 PR_ASSERT(sd->lower != NULL);
304
305 /* test for new style stack */
306 while (NULL != layer->higher)
307 layer = layer->higher;
308 newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FA LSE;
309 newstack = PR_NEW(PRFileDesc);
310 if (NULL == newstack)
311 {
312 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
313 return -1;
314 }
315 *newstack = *sd; /* make a copy of the accepting layer */
316
317 nbytes = sd->lower->methods->acceptread(
318 sd->lower, nd, raddr, buf, amount, t);
319 if (-1 == nbytes)
320 {
321 PR_DELETE(newstack);
322 return nbytes;
323 }
324 if (newstyle_stack) {
325 newstack->lower = *nd;
326 (*nd)->higher = newstack;
327 *nd = newstack;
328 return nbytes;
329 } else {
330 /* this PR_PushIOLayer call cannot fail */
331 rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
332 PR_ASSERT(PR_SUCCESS == rv);
333 return nbytes;
334 }
335 }
336
337 static PRInt32 PR_CALLBACK pl_DefTransmitfile (
338 PRFileDesc *sd, PRFileDesc *fd, const void *headers, PRInt32 hlen,
339 PRTransmitFileFlags flags, PRIntervalTime t)
340 {
341 PR_ASSERT(sd != NULL);
342 PR_ASSERT(sd->lower != NULL);
343
344 return sd->lower->methods->transmitfile(
345 sd->lower, fd, headers, hlen, flags, t);
346 }
347
348 static PRStatus PR_CALLBACK pl_DefGetsockname (PRFileDesc *fd, PRNetAddr *addr)
349 {
350 PR_ASSERT(fd != NULL);
351 PR_ASSERT(fd->lower != NULL);
352
353 return (fd->lower->methods->getsockname)(fd->lower, addr);
354 }
355
356 static PRStatus PR_CALLBACK pl_DefGetpeername (PRFileDesc *fd, PRNetAddr *addr)
357 {
358 PR_ASSERT(fd != NULL);
359 PR_ASSERT(fd->lower != NULL);
360
361 return (fd->lower->methods->getpeername)(fd->lower, addr);
362 }
363
364 static PRStatus PR_CALLBACK pl_DefGetsocketoption (
365 PRFileDesc *fd, PRSocketOptionData *data)
366 {
367 PR_ASSERT(fd != NULL);
368 PR_ASSERT(fd->lower != NULL);
369
370 return (fd->lower->methods->getsocketoption)(fd->lower, data);
371 }
372
373 static PRStatus PR_CALLBACK pl_DefSetsocketoption (
374 PRFileDesc *fd, const PRSocketOptionData *data)
375 {
376 PR_ASSERT(fd != NULL);
377 PR_ASSERT(fd->lower != NULL);
378
379 return (fd->lower->methods->setsocketoption)(fd->lower, data);
380 }
381
382 static PRInt32 PR_CALLBACK pl_DefSendfile (
383 PRFileDesc *sd, PRSendFileData *sfd,
384 PRTransmitFileFlags flags, PRIntervalTime timeout)
385 {
386 PR_ASSERT(sd != NULL);
387 PR_ASSERT(sd->lower != NULL);
388
389 return sd->lower->methods->sendfile(
390 sd->lower, sfd, flags, timeout);
391 }
392
393 /* Methods for the top of the stack. Just call down to the next fd. */
394 static PRIOMethods pl_methods = {
395 PR_DESC_LAYERED,
396 pl_TopClose,
397 pl_DefRead,
398 pl_DefWrite,
399 pl_DefAvailable,
400 pl_DefAvailable64,
401 pl_DefFsync,
402 pl_DefSeek,
403 pl_DefSeek64,
404 pl_DefFileInfo,
405 pl_DefFileInfo64,
406 pl_DefWritev,
407 pl_DefConnect,
408 pl_TopAccept,
409 pl_DefBind,
410 pl_DefListen,
411 pl_DefShutdown,
412 pl_DefRecv,
413 pl_DefSend,
414 pl_DefRecvfrom,
415 pl_DefSendto,
416 pl_DefPoll,
417 pl_DefAcceptread,
418 pl_DefTransmitfile,
419 pl_DefGetsockname,
420 pl_DefGetpeername,
421 (PRReservedFN)_PR_InvalidInt,
422 (PRReservedFN)_PR_InvalidInt,
423 pl_DefGetsocketoption,
424 pl_DefSetsocketoption,
425 pl_DefSendfile,
426 pl_DefConnectcontinue,
427 (PRReservedFN)_PR_InvalidInt,
428 (PRReservedFN)_PR_InvalidInt,
429 (PRReservedFN)_PR_InvalidInt,
430 (PRReservedFN)_PR_InvalidInt
431 };
432
433 PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods(void)
434 {
435 return &pl_methods;
436 } /* PR_GetDefaultIOMethods */
437
438 PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub(
439 PRDescIdentity ident, const PRIOMethods *methods)
440 {
441 PRFileDesc *fd = NULL;
442 PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident));
443 if ((PR_NSPR_IO_LAYER == ident) || (PR_TOP_IO_LAYER == ident))
444 PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
445 else
446 {
447 fd = PR_NEWZAP(PRFileDesc);
448 if (NULL == fd)
449 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
450 else
451 {
452 fd->methods = methods;
453 fd->dtor = pl_FDDestructor;
454 fd->identity = ident;
455 }
456 }
457 return fd;
458 } /* PR_CreateIOLayerStub */
459
460 /*
461 * PR_CreateIOLayer
462 * Create a new style stack, where the stack top is a dummy header.
463 * Unlike the old style stacks, the contents of the stack head
464 * are not modified when a layer is pushed onto or popped from a ne w
465 * style stack.
466 */
467
468 PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayer(PRFileDesc *top)
469 {
470 PRFileDesc *fd = NULL;
471
472 fd = PR_NEWZAP(PRFileDesc);
473 if (NULL == fd)
474 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
475 else
476 {
477 fd->methods = &pl_methods;
478 fd->dtor = pl_FDDestructor;
479 fd->identity = PR_IO_LAYER_HEAD;
480 fd->higher = NULL;
481 fd->lower = top;
482 top->higher = fd;
483 top->lower = NULL;
484 }
485 return fd;
486 } /* PR_CreateIOLayer */
487
488 /*
489 * _PR_DestroyIOLayer
490 * Delete the stack head of a new style stack.
491 */
492
493 static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack)
494 {
495 if (NULL == stack)
496 return PR_FAILURE;
497 else {
498 PR_DELETE(stack);
499 return PR_SUCCESS;
500 }
501 } /* _PR_DestroyIOLayer */
502
503 PR_IMPLEMENT(PRStatus) PR_PushIOLayer(
504 PRFileDesc *stack, PRDescIdentity id, PRFileDesc *fd)
505 {
506 PRFileDesc *insert = PR_GetIdentitiesLayer(stack, id);
507
508 PR_ASSERT(fd != NULL);
509 PR_ASSERT(stack != NULL);
510 PR_ASSERT(insert != NULL);
511 PR_ASSERT(PR_IO_LAYER_HEAD != id);
512 if ((NULL == stack) || (NULL == fd) || (NULL == insert))
513 {
514 PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
515 return PR_FAILURE;
516 }
517
518 if (stack == insert)
519 {
520 /* going on top of the stack */
521 /* old-style stack */
522 PRFileDesc copy = *stack;
523 *stack = *fd;
524 *fd = copy;
525 fd->higher = stack;
526 if (fd->lower)
527 {
528 PR_ASSERT(fd->lower->higher == stack);
529 fd->lower->higher = fd;
530 }
531 stack->lower = fd;
532 stack->higher = NULL;
533 } else {
534 /*
535 * going somewhere in the middle of the stack for both old and n ew
536 * style stacks, or going on top of stack for new style stack
537 */
538 fd->lower = insert;
539 fd->higher = insert->higher;
540
541 insert->higher->lower = fd;
542 insert->higher = fd;
543 }
544
545 return PR_SUCCESS;
546 }
547
548 PR_IMPLEMENT(PRFileDesc*) PR_PopIOLayer(PRFileDesc *stack, PRDescIdentity id)
549 {
550 PRFileDesc *extract = PR_GetIdentitiesLayer(stack, id);
551
552 PR_ASSERT(0 != id);
553 PR_ASSERT(NULL != stack);
554 PR_ASSERT(NULL != extract);
555 if ((NULL == stack) || (0 == id) || (NULL == extract))
556 {
557 PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
558 return NULL;
559 }
560
561 if (extract == stack) {
562 /* popping top layer of the stack */
563 /* old style stack */
564 PRFileDesc copy = *stack;
565 extract = stack->lower;
566 *stack = *extract;
567 *extract = copy;
568 stack->higher = NULL;
569 if (stack->lower) {
570 PR_ASSERT(stack->lower->higher == extract);
571 stack->lower->higher = stack;
572 }
573 } else if ((PR_IO_LAYER_HEAD == stack->identity) &&
574 (extract == stack->lower) && (extract->l ower == NULL)) {
575 /*
576 * new style stack
577 * popping the only layer in the stack; delete the stack too
578 */
579 stack->lower = NULL;
580 _PR_DestroyIOLayer(stack);
581 } else {
582 /* for both kinds of stacks */
583 extract->lower->higher = extract->higher;
584 extract->higher->lower = extract->lower;
585 }
586 extract->higher = extract->lower = NULL;
587 return extract;
588 } /* PR_PopIOLayer */
589
590 #define ID_CACHE_INCREMENT 16
591 typedef struct _PRIdentity_cache
592 {
593 PRLock *ml;
594 char **name;
595 PRIntn length;
596 PRDescIdentity ident;
597 } _PRIdentity_cache;
598
599 static _PRIdentity_cache identity_cache;
600
601 PR_IMPLEMENT(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name)
602 {
603 PRDescIdentity identity, length;
604 char **names = NULL, *name = NULL, **old = NULL;
605
606 if (!_pr_initialized) _PR_ImplicitInitialization();
607
608 PR_ASSERT((PRDescIdentity)0x7fff > identity_cache.ident);
609
610 if (NULL != layer_name)
611 {
612 name = (char*)PR_Malloc(strlen(layer_name) + 1);
613 if (NULL == name)
614 {
615 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
616 return PR_INVALID_IO_LAYER;
617 }
618 strcpy(name, layer_name);
619 }
620
621 /* this initial code runs unsafe */
622 retry:
623 PR_ASSERT(NULL == names);
624 /*
625 * In the initial round, both identity_cache.ident and
626 * identity_cache.length are 0, so (identity_cache.ident + 1) is greater
627 * than length. In later rounds, identity_cache.ident is always less
628 * than length, so (identity_cache.ident + 1) can be equal to but cannot
629 * be greater than length.
630 */
631 length = identity_cache.length;
632 if ((identity_cache.ident + 1) >= length)
633 {
634 length += ID_CACHE_INCREMENT;
635 names = (char**)PR_CALLOC(length * sizeof(char*));
636 if (NULL == names)
637 {
638 if (NULL != name) PR_DELETE(name);
639 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
640 return PR_INVALID_IO_LAYER;
641 }
642 }
643
644 /* now we get serious about thread safety */
645 PR_Lock(identity_cache.ml);
646 PR_ASSERT(identity_cache.length == 0 ||
647 identity_cache.ident < identity_cache.length);
648 identity = identity_cache.ident + 1;
649 if (identity >= identity_cache.length) /* there's no room */
650 {
651 /* we have to do something - hopefully it's already done */
652 if ((NULL != names) && (identity < length))
653 {
654 /* what we did is still okay */
655 memcpy(
656 names, identity_cache.name,
657 identity_cache.length * sizeof(char*));
658 old = identity_cache.name;
659 identity_cache.name = names;
660 identity_cache.length = length;
661 names = NULL;
662 }
663 else
664 {
665 PR_Unlock(identity_cache.ml);
666 if (NULL != names) PR_DELETE(names);
667 goto retry;
668 }
669 }
670 if (NULL != name) /* there's a name to be stored */
671 {
672 identity_cache.name[identity] = name;
673 }
674 identity_cache.ident = identity;
675 PR_ASSERT(identity_cache.ident < identity_cache.length);
676 PR_Unlock(identity_cache.ml);
677
678 if (NULL != old) PR_DELETE(old);
679 if (NULL != names) PR_DELETE(names);
680
681 return identity;
682 } /* PR_GetUniqueIdentity */
683
684 PR_IMPLEMENT(const char*) PR_GetNameForIdentity(PRDescIdentity ident)
685 {
686 if (!_pr_initialized) _PR_ImplicitInitialization();
687
688 if (PR_TOP_IO_LAYER == ident) return NULL;
689
690 PR_ASSERT(ident <= identity_cache.ident);
691 return (ident > identity_cache.ident) ? NULL : identity_cache.name[ident];
692 } /* PR_GetNameForIdentity */
693
694 PR_IMPLEMENT(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd)
695 {
696 PR_ASSERT(NULL != fd);
697 if (PR_IO_LAYER_HEAD == fd->identity) {
698 PR_ASSERT(NULL != fd->lower);
699 return fd->lower->identity;
700 } else
701 return fd->identity;
702 } /* PR_GetLayersIdentity */
703
704 PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity i d)
705 {
706 PRFileDesc *layer = fd;
707
708 if (PR_TOP_IO_LAYER == id) {
709 if (PR_IO_LAYER_HEAD == fd->identity)
710 return fd->lower;
711 else
712 return fd;
713 }
714
715 for (layer = fd; layer != NULL; layer = layer->lower)
716 {
717 if (id == layer->identity) return layer;
718 }
719 for (layer = fd; layer != NULL; layer = layer->higher)
720 {
721 if (id == layer->identity) return layer;
722 }
723 return NULL;
724 } /* PR_GetIdentitiesLayer */
725
726 void _PR_InitLayerCache(void)
727 {
728 memset(&identity_cache, 0, sizeof(identity_cache));
729 identity_cache.ml = PR_NewLock();
730 PR_ASSERT(NULL != identity_cache.ml);
731 } /* _PR_InitLayerCache */
732
733 void _PR_CleanupLayerCache(void)
734 {
735 if (identity_cache.ml)
736 {
737 PR_DestroyLock(identity_cache.ml);
738 identity_cache.ml = NULL;
739 }
740
741 if (identity_cache.name)
742 {
743 PRDescIdentity ident;
744
745 for (ident = 0; ident <= identity_cache.ident; ident++)
746 PR_DELETE(identity_cache.name[ident]);
747
748 PR_DELETE(identity_cache.name);
749 }
750 } /* _PR_CleanupLayerCache */
751
752 /* prlayer.c */
OLDNEW
« no previous file with comments | « nspr/pr/src/io/pripv6.c ('k') | nspr/pr/src/io/prlog.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698