File Coverage

blib/lib/Linux/Perl/eventfd.pm
Criterion Covered Total %
statement 41 42 97.6
branch 5 6 83.3
condition 10 13 76.9
subroutine 10 10 100.0
pod 2 2 100.0
total 68 73 93.1


line stmt bran cond sub pod time code
1             package Linux::Perl::eventfd;
2              
3             =encoding utf-8
4              
5             =head1 NAME
6              
7             Linux::Perl::eventfd
8              
9             =head1 SYNOPSIS
10              
11             my $efd = Linux::Perl::eventfd->new(
12             initval => 4,
13             flags => [ 'NONBLOCK', 'CLOEXEC' ], #only on 2.6.27+
14             );
15              
16             #or, e.g., Linux::Perl::eventfd::x86_64
17              
18             my $fd = $efd->fileno();
19              
20             $efd->add(12);
21              
22             my $read = $efd->read();
23              
24             =head1 DESCRIPTION
25              
26             This is an interface to the C/C system call.
27             (C is only called if the given parameters require it.)
28              
29             This class inherits from L.
30              
31             =cut
32              
33 5     5   153161 use strict;
  5         12  
  5         144  
34 5     5   22 use warnings;
  5         10  
  5         156  
35              
36 5     5   20 use parent 'Linux::Perl::Base::TimerEventFD';
  5         10  
  5         34  
37              
38 5     5   186 use Module::Load;
  5         10  
  5         38  
39              
40 5     5   1260 use Linux::Perl;
  5         14  
  5         106  
41              
42 5     5   24 use Linux::Perl::Endian;
  5         9  
  5         102  
43 5     5   1953 use Linux::Perl::ParseFlags;
  5         11  
  5         1130  
44              
45             use constant {
46 5         1734 _flag_SEMAPHORE => 1,
47 5     5   30 };
  5         5  
48              
49             =head1 METHODS
50              
51             =head2 I->new( %OPTS )
52              
53             %OPTS is:
54              
55             =over
56              
57             =item * C - Optional, as described in the eventfd documentation.
58             Defaults to 0.
59              
60             =item * C - Optional, an array reference of any or all of:
61             C, C, C. See C for
62             more details.
63              
64             Note that, in conformity with Perl convention, this module honors
65             the $^F variable, which in its default configuration causes CLOEXEC
66             even if the flag is not given. To have a non-CLOEXEC eventfd instance,
67             then, set $^F to a high enough value that the eventfd file descriptor
68             will not be an “OS” filehandle, e.g.:
69              
70             my $eventfd = do {
71             local $^F = 1000;
72             Linux::Perl::eventfd->new();
73             };
74              
75             =back
76              
77             =cut
78              
79             sub new {
80 12     12 1 578824 my ($class, %opts) = @_;
81              
82 12         228 local ($!, $^E);
83              
84 12   66     315 my $arch_module = $class->can('NR_eventfd') && $class;
85 12   66     92 $arch_module ||= do {
86 8         1679 require Linux::Perl::ArchLoader;
87 8         55 Linux::Perl::ArchLoader::get_arch_module($class);
88             };
89              
90 12   100     135 my $initval = 0 + ( $opts{'initval'} || 0 );
91              
92 12         20 my $is_cloexec;
93              
94 12         98 my $flags = Linux::Perl::ParseFlags::parse($arch_module, $opts{'flags'});
95              
96 12 100       84 my $call = 'NR_' . ($flags ? 'eventfd2' : 'eventfd');
97              
98 12   100     348 my $fd = Linux::Perl::call( 0 + $arch_module->$call(), $initval, $flags || () );
99              
100             #Force CLOEXEC if the flag was given.
101 12 100       151 local $^F = 0 if $flags & $arch_module->_flag_CLOEXEC();
102              
103 12         378 open my $fh, '+<&=' . $fd;
104              
105 12         235 return bless [$fh], $arch_module;
106             }
107              
108             #----------------------------------------------------------------------
109              
110             =head2 $val = I->read()
111              
112             Reads a value from the eventfd instance. Sets C<$!> and returns undef
113             on error.
114              
115             =cut
116              
117             *read = __PACKAGE__->can('_read');
118              
119             #----------------------------------------------------------------------
120              
121             =head2 I->add( NUMBER )
122              
123             Adds NUMBER to the counter. Returns undef and sets C<$!> on failure.
124              
125             =cut
126              
127             my $packed;
128              
129             sub add {
130 8 50   8 1 22023 if ($_[0]->_PERL_CAN_64BIT()) {
131 8         40 $packed = pack 'Q', $_[1];
132             }
133             elsif (Linux::Perl::Endian::SYSTEM_IS_BIG_ENDIAN) {
134             $packed = pack 'x4N', $_[1];
135             }
136             else {
137 0         0 $packed = pack 'Vx4', $_[1];
138             }
139              
140 8   50     73 return syswrite( $_[0][0], $packed ) && 1;
141             }
142              
143             1;