File Coverage

blib/lib/Riak/Light/Timeout/Alarm.pm
Criterion Covered Total %
statement 50 53 94.3
branch 8 10 80.0
condition n/a
subroutine 11 12 91.6
pod 0 4 0.0
total 69 79 87.3


line stmt bran cond sub pod time code
1             #
2             # This file is part of Riak-Light
3             #
4             # This software is copyright (c) 2013 by Weborama.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9             ## no critic (RequireUseStrict, RequireUseWarnings)
10             package Riak::Light::Timeout::Alarm;
11             {
12             $Riak::Light::Timeout::Alarm::VERSION = '0.12';
13             }
14             ## use critic
15              
16 2     2   60324 use POSIX qw(ETIMEDOUT ECONNRESET);
  2         6591  
  2         13  
17 2     2   2135 use Time::HiRes qw(alarm);
  2         1430  
  2         16  
18 2     2   2493 use Riak::Light::Util qw(is_windows);
  2         5  
  2         106  
19 2     2   11 use Carp;
  2         5  
  2         105  
20 2     2   10 use Moo;
  2         2  
  2         18  
21 2     2   646 use Types::Standard -types;
  2         3  
  2         30  
22             with 'Riak::Light::Timeout';
23              
24             # ABSTRACT: proxy to read/write using Alarm as a timeout provider ( Not Safe: can clobber previous alarm )
25              
26             has socket => ( is => 'ro', required => 1 );
27             has in_timeout => ( is => 'ro', isa => Num, default => sub {0.5} );
28             has out_timeout => ( is => 'ro', isa => Num, default => sub {0.5} );
29             has is_valid => ( is => 'rw', isa => Bool, default => sub {1} );
30              
31             sub BUILD {
32              
33             # from perldoc perlport
34             # alarm:
35             # Emulated using timers that must be explicitly polled whenever
36             # Perl wants to dispatch "safe signals" and therefore cannot
37             # interrupt blocking system calls (Win32)
38              
39 3 100   3 0 238 croak "Alarm cannot interrupt blocking system calls in Win32!"
40             if is_windows();
41              
42 2         117 carp "Not Safe: can clobber previous alarm";
43             }
44              
45             sub clean {
46 1     1 0 34 $_[0]->socket->close;
47 1         223 $_[0]->is_valid(0);
48             }
49              
50             sub sysread {
51 3     3 0 11 my $self = shift;
52 3 50       109 $self->is_valid
53             or $! = ECONNRESET,
54             return; ## no critic (RequireLocalizedPunctuationVars)
55              
56 3         24 my $buffer;
57 3         19 my $seconds = $self->in_timeout;
58              
59 3         6 my $result = eval {
60 3     1   36 local $SIG{'ALRM'} = sub { croak 'Timeout !' };
  1         49  
61 3         17 alarm($seconds);
62              
63 3         36 my $readed = $self->socket->sysread(@_);
64              
65 3         502928 alarm(0);
66              
67 2         15 $buffer = $_[0]; # NECESSARY, timeout does not map the alias @_ !!
68 2         37 $readed;
69             };
70 3 100       1174 if ($@) {
71 1         9 $self->clean();
72 1         37 $! = ETIMEDOUT; ## no critic (RequireLocalizedPunctuationVars)
73             }
74             else {
75 2         18 $_[0] = $buffer;
76             }
77              
78 3         16 $result;
79             }
80              
81             sub syswrite {
82 3     3 0 5 my $self = shift;
83 3 100       57 $self->is_valid
84             or $! = ECONNRESET,
85             return; ## no critic (RequireLocalizedPunctuationVars)
86              
87 2         709 my $seconds = $self->out_timeout;
88 2         5 my $result = eval {
89 2     0   96 local $SIG{'ALRM'} = sub { croak 'Timeout !' };
  0         0  
90 2         23 alarm($seconds);
91              
92 2         46 my $readed = $self->socket->syswrite(@_);
93              
94 2         189 alarm(0);
95              
96 2         15 $readed;
97             };
98 2 50       7 if ($@) {
99 0         0 $self->clean();
100 0         0 $! = ETIMEDOUT; ## no critic (RequireLocalizedPunctuationVars)
101             }
102              
103 2         6 $result;
104             }
105              
106             1;
107              
108              
109             =pod
110              
111             =head1 NAME
112              
113             Riak::Light::Timeout::Alarm - proxy to read/write using Alarm as a timeout provider ( Not Safe: can clobber previous alarm )
114              
115             =head1 VERSION
116              
117             version 0.12
118              
119             =head1 DESCRIPTION
120              
121             Internal class
122              
123             =head1 AUTHORS
124              
125             =over 4
126              
127             =item *
128              
129             Tiago Peczenyj
130              
131             =item *
132              
133             Damien Krotkine
134              
135             =back
136              
137             =head1 COPYRIGHT AND LICENSE
138              
139             This software is copyright (c) 2013 by Weborama.
140              
141             This is free software; you can redistribute it and/or modify it under
142             the same terms as the Perl 5 programming language system itself.
143              
144             =cut
145              
146              
147             __END__