File Coverage

blib/lib/Signals/XSIG/Meta.pm
Criterion Covered Total %
statement 103 105 98.1
branch 34 40 85.0
condition 9 12 75.0
subroutine 14 14 100.0
pod n/a
total 160 171 93.5


line stmt bran cond sub pod time code
1             package Signals::XSIG::Meta;
2 13     13   121 use Carp;
  13         23  
  13         679  
3 13     13   54 use strict;
  13         20  
  13         184  
4 13     13   43 use warnings;
  13         18  
  13         3860  
5              
6             *_qualify_handler = \&Signals::XSIG::_qualify_handler;
7              
8             # A handler for a multi-signal handler (as in, multiple handlers for
9             # a signal, not handler for multiple signals).
10             #
11             # All elements of %Signals::XSIG::ZSIG will have this object type.
12             # Also see Signals::XSIG::Meta56 for an alternate implementation
13             # that gets around the restriction of older perls in calling FETCH
14             # and STORE for a tied array class with negative indices.
15              
16             sub _new {
17 1233     1233   2046 my ($pkg, $sig, @handlers) = @_;
18             my $good = defined $Signals::XSIG::SIGTABLE{$sig} &&
19 1233   33     3250 !defined($Signals::XSIG::alias{"sub:$sig"});
20 1233 50       1690 if ($good) {
21 1233         1499 @handlers = map { _qualify_handler($_) } @handlers;
  1021         1473  
22             }
23             my $self = {
24             key => $sig,
25             handlers => [ @handlers ],
26             start => 0,
27             xh => [],
28             ta => [],
29             good => $good,
30 32     32   2052 sigacshun => sub { Signals::XSIG::_sigaction($sig, @_) }
31 1233         6646 };
32 1233         1611 tie @{$self->{ta}}, 'Signals::XSIG::TieArray', $sig;
  1233         2826  
33 1233         1652 bless $self, $pkg;
34 1233         1501 return $self->_refresh;
35             }
36              
37             sub _refresh {
38 3138     3138   3221 my $self = shift(@_);
39 3138 100       6024 return $self if !$Signals::XSIG::_REFRESH;
40 2200 50       3000 if (!$self->{good}) {
41 0         0 Carp::cluck("_refresh: called on bad signal " . $self->{key});
42 0         0 return;
43             }
44 2200         1963 my $seen_default = 0;
45 2200         2781 $self->{xh} = [];
46 2200         2377 my $start = $self->{start} - 1;
47 2200         1984 my $ignore_main_default = 0;
48 2200         2231 for my $h (@{$self->{handlers}}) {
  2200         2813  
49 2869         2480 $start++;
50 2869 100       3731 next if !defined $h;
51 771 100       1168 next if $h eq '';
52 757 100       1087 $ignore_main_default = 1 if $start != 0;
53 757 100       1064 next if $h eq 'IGNORE';
54 715 100       998 if ($h eq 'DEFAULT') {
55 15 50 66     50 next if $start == 0 && $ignore_main_default;
56 15 100       43 next if $seen_default++;
57 14         19 push @{$self->{xh}}, 'DEFAULT';
  14         27  
58             } else {
59 700 100       1160 next if !defined &$h;
60 625         590 push @{$self->{xh}}, $h;
  625         1200  
61             }
62             }
63 2200 100 100     3456 if ($Signals::XSIG::_INITIALIZED && @{$self->{xh}}) {
  1261 100       2693  
64 477         1603 $Signals::XSIG::OSIG{$self->{key}} = $self->{sigacshun};
65             } elsif ($Signals::XSIG::_INITIALIZED) {
66 13     13   79 no warnings 'signal', 'uninitialized';
  13         25  
  13         6083  
67 784 50       1413 die unless $self->{key}; # ASSERT
68 784         3516 $Signals::XSIG::OSIG{$self->{key}} = undef;
69             }
70 2200         5060 return $self;
71             }
72              
73             sub _fetch {
74 1498     1498   1742 my ($self, $index) = @_;
75 1498         2096 $index -= $self->{start};
76 1498 100       2091 return if $index < 0;
77 1496         2791 return $self->{handlers}[$index];
78             }
79              
80             sub _store {
81 950     950   1309 my ($self, $index, $handler) = @_;
82 950         1121 $index -= $self->{start};
83 950         1517 while ($index < 0) {
84 10         9 unshift @{$self->{handlers}}, undef;
  10         14  
85 10         8 $index++;
86 10         12 $self->{start}--;
87             }
88 950         939 while ($index > $#{$self->{handlers}}) {
  1120         1858  
89 170         153 push @{$self->{handlers}}, undef;
  170         192  
90             }
91 950         1235 my $old = $self->{handlers}[$index];
92 950 50       1488 if ($self->{good}) {
93 950         1462 $handler = _qualify_handler($handler);
94             }
95 950         1287 $self->{handlers}[$index] = $handler;
96 950         1633 $self->_refresh;
97 950         31650 return $old;
98             }
99              
100             sub _size {
101 11     11   17 my $self = shift(@_);
102 11         11 return scalar @{$self->{handlers}};
  11         29  
103             }
104              
105             sub _unshift {
106 4     4   16 my ($self, @list) = @_;
107 4         5 unshift @{$self->{handlers}}, @list;
  4         12  
108 4         7 $self->{start} -= @list;
109 4         8 $self->_refresh;
110 4         9 return $self->_size;
111             }
112              
113             sub _push {
114 7     7   19 my ($self, @list) = @_;
115 7 100       8 if (@{$self->{handlers}} + $self->{start} <= 0) {
  7         19  
116             # push should not set the default handler
117 2         4 unshift @list, undef;
118             }
119 7         17 push @{$self->{handlers}}, @list;
  7         15  
120 7         16 $self->_refresh;
121 7         41 return $self->_size;
122             }
123              
124             sub _shift {
125 4     4   6 my $self = shift(@_);
126 4 100       18 return if $self->{start} >= 0;
127 2         5 $self->{start}++;
128 2         6 $self->_refresh;
129 2         3 return shift @{$self->{handlers}};
  2         8  
130             }
131              
132             sub _pop {
133 5     5   8 my $self = shift(@_);
134 5 50       12 return if $self->{start} > 0;
135 5 100 100     13 return if $self->{start} == 0 && $#{$self->{handlers}} == 0;
  2         7  
136 4         4 my $val = pop @{$self->{handlers}};
  4         8  
137 4         10 $self->_refresh;
138 4         11 return $val;
139             }
140              
141             1;