OLD | NEW |
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | 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 | 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 | 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/. */ | 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | 5 |
6 /* | 6 /* |
7 ** File: prlayer.c | 7 ** File: prlayer.c |
8 ** Description: Routines for handling pushable protocol modules on sockets. | 8 ** Description: Routines for handling pushable protocol modules on sockets. |
9 */ | 9 */ |
10 | 10 |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 } | 516 } |
517 | 517 |
518 if (stack == insert) | 518 if (stack == insert) |
519 { | 519 { |
520 /* going on top of the stack */ | 520 /* going on top of the stack */ |
521 /* old-style stack */ | 521 /* old-style stack */ |
522 PRFileDesc copy = *stack; | 522 PRFileDesc copy = *stack; |
523 *stack = *fd; | 523 *stack = *fd; |
524 *fd = copy; | 524 *fd = copy; |
525 fd->higher = stack; | 525 fd->higher = stack; |
| 526 if (fd->lower) |
| 527 { |
| 528 PR_ASSERT(fd->lower->higher == stack); |
| 529 fd->lower->higher = fd; |
| 530 } |
526 stack->lower = fd; | 531 stack->lower = fd; |
527 stack->higher = NULL; | 532 stack->higher = NULL; |
528 } else { | 533 } else { |
529 /* | 534 /* |
530 * going somewhere in the middle of the stack for both old and n
ew | 535 * going somewhere in the middle of the stack for both old and n
ew |
531 * style stacks, or going on top of stack for new style stack | 536 * style stacks, or going on top of stack for new style stack |
532 */ | 537 */ |
533 fd->lower = insert; | 538 fd->lower = insert; |
534 fd->higher = insert->higher; | 539 fd->higher = insert->higher; |
535 | 540 |
(...skipping 18 matching lines...) Expand all Loading... |
554 } | 559 } |
555 | 560 |
556 if (extract == stack) { | 561 if (extract == stack) { |
557 /* popping top layer of the stack */ | 562 /* popping top layer of the stack */ |
558 /* old style stack */ | 563 /* old style stack */ |
559 PRFileDesc copy = *stack; | 564 PRFileDesc copy = *stack; |
560 extract = stack->lower; | 565 extract = stack->lower; |
561 *stack = *extract; | 566 *stack = *extract; |
562 *extract = copy; | 567 *extract = copy; |
563 stack->higher = NULL; | 568 stack->higher = NULL; |
| 569 if (stack->lower) { |
| 570 PR_ASSERT(stack->lower->higher == extract); |
| 571 stack->lower->higher = stack; |
| 572 } |
564 } else if ((PR_IO_LAYER_HEAD == stack->identity) && | 573 } else if ((PR_IO_LAYER_HEAD == stack->identity) && |
565 (extract == stack->lower) && (extract->l
ower == NULL)) { | 574 (extract == stack->lower) && (extract->l
ower == NULL)) { |
566 /* | 575 /* |
567 * new style stack | 576 * new style stack |
568 * popping the only layer in the stack; delete the stack
too | 577 * popping the only layer in the stack; delete the stack
too |
569 */ | 578 */ |
570 stack->lower = NULL; | 579 stack->lower = NULL; |
571 _PR_DestroyIOLayer(stack); | 580 _PR_DestroyIOLayer(stack); |
572 } else { | 581 } else { |
573 /* for both kinds of stacks */ | 582 /* for both kinds of stacks */ |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 { | 614 { |
606 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); | 615 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); |
607 return PR_INVALID_IO_LAYER; | 616 return PR_INVALID_IO_LAYER; |
608 } | 617 } |
609 strcpy(name, layer_name); | 618 strcpy(name, layer_name); |
610 } | 619 } |
611 | 620 |
612 /* this initial code runs unsafe */ | 621 /* this initial code runs unsafe */ |
613 retry: | 622 retry: |
614 PR_ASSERT(NULL == names); | 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 */ |
615 length = identity_cache.length; | 631 length = identity_cache.length; |
616 if (length < (identity_cache.ident + 1)) | 632 if ((identity_cache.ident + 1) >= length) |
617 { | 633 { |
618 length += ID_CACHE_INCREMENT; | 634 length += ID_CACHE_INCREMENT; |
619 names = (char**)PR_CALLOC(length * sizeof(char*)); | 635 names = (char**)PR_CALLOC(length * sizeof(char*)); |
620 if (NULL == names) | 636 if (NULL == names) |
621 { | 637 { |
622 if (NULL != name) PR_DELETE(name); | 638 if (NULL != name) PR_DELETE(name); |
623 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); | 639 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); |
624 return PR_INVALID_IO_LAYER; | 640 return PR_INVALID_IO_LAYER; |
625 } | 641 } |
626 } | 642 } |
627 | 643 |
628 /* now we get serious about thread safety */ | 644 /* now we get serious about thread safety */ |
629 PR_Lock(identity_cache.ml); | 645 PR_Lock(identity_cache.ml); |
630 PR_ASSERT(identity_cache.ident <= identity_cache.length); | 646 PR_ASSERT(identity_cache.length == 0 || |
| 647 identity_cache.ident < identity_cache.length); |
631 identity = identity_cache.ident + 1; | 648 identity = identity_cache.ident + 1; |
632 if (identity > identity_cache.length) /* there's no room */ | 649 if (identity >= identity_cache.length) /* there's no room */ |
633 { | 650 { |
634 /* we have to do something - hopefully it's already done */ | 651 /* we have to do something - hopefully it's already done */ |
635 if ((NULL != names) && (length >= identity)) | 652 if ((NULL != names) && (identity < length)) |
636 { | 653 { |
637 /* what we did is still okay */ | 654 /* what we did is still okay */ |
638 memcpy( | 655 memcpy( |
639 names, identity_cache.name, | 656 names, identity_cache.name, |
640 identity_cache.length * sizeof(char*)); | 657 identity_cache.length * sizeof(char*)); |
641 old = identity_cache.name; | 658 old = identity_cache.name; |
642 identity_cache.name = names; | 659 identity_cache.name = names; |
643 identity_cache.length = length; | 660 identity_cache.length = length; |
644 names = NULL; | 661 names = NULL; |
645 } | 662 } |
646 else | 663 else |
647 { | 664 { |
648 PR_ASSERT(identity_cache.ident <= identity_cache.length); | |
649 PR_Unlock(identity_cache.ml); | 665 PR_Unlock(identity_cache.ml); |
650 if (NULL != names) PR_DELETE(names); | 666 if (NULL != names) PR_DELETE(names); |
651 goto retry; | 667 goto retry; |
652 } | 668 } |
653 } | 669 } |
654 if (NULL != name) /* there's a name to be stored */ | 670 if (NULL != name) /* there's a name to be stored */ |
655 { | 671 { |
656 identity_cache.name[identity] = name; | 672 identity_cache.name[identity] = name; |
657 } | 673 } |
658 identity_cache.ident = identity; | 674 identity_cache.ident = identity; |
659 PR_ASSERT(identity_cache.ident <= identity_cache.length); | 675 PR_ASSERT(identity_cache.ident < identity_cache.length); |
660 PR_Unlock(identity_cache.ml); | 676 PR_Unlock(identity_cache.ml); |
661 | 677 |
662 if (NULL != old) PR_DELETE(old); | 678 if (NULL != old) PR_DELETE(old); |
663 if (NULL != names) PR_DELETE(names); | 679 if (NULL != names) PR_DELETE(names); |
664 | 680 |
665 return identity; | 681 return identity; |
666 } /* PR_GetUniqueIdentity */ | 682 } /* PR_GetUniqueIdentity */ |
667 | 683 |
668 PR_IMPLEMENT(const char*) PR_GetNameForIdentity(PRDescIdentity ident) | 684 PR_IMPLEMENT(const char*) PR_GetNameForIdentity(PRDescIdentity ident) |
669 { | 685 { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 PRDescIdentity ident; | 743 PRDescIdentity ident; |
728 | 744 |
729 for (ident = 0; ident <= identity_cache.ident; ident++) | 745 for (ident = 0; ident <= identity_cache.ident; ident++) |
730 PR_DELETE(identity_cache.name[ident]); | 746 PR_DELETE(identity_cache.name[ident]); |
731 | 747 |
732 PR_DELETE(identity_cache.name); | 748 PR_DELETE(identity_cache.name); |
733 } | 749 } |
734 } /* _PR_CleanupLayerCache */ | 750 } /* _PR_CleanupLayerCache */ |
735 | 751 |
736 /* prlayer.c */ | 752 /* prlayer.c */ |
OLD | NEW |