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.10';
13             }
14             ## use critic
15              
16 2     2   60642 use POSIX qw(ETIMEDOUT ECONNRESET);
  2         7547  
  2         18  
17 2     2   3058 use Time::HiRes qw(alarm);
  2         2059  
  2         13  
18 2     2   1602 use Riak::Light::Util qw(is_windows);
  2         5  
  2         105  
19 2     2   13 use Carp;
  2         4  
  2         103  
20 2     2   11 use Moo;
  2         3  
  2         20  
21 2     2   797 use Types::Standard -types;
  2         6  
  2         32  
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 269 croak "Alarm cannot interrupt blocking system calls in Win32!"
40             if is_windows();
41              
42 2         139 carp "Not Safe: can clobber previous alarm";
43             }
44              
45             sub clean {
46 1     1 0 39 $_[0]->socket->close;
47 1         244 $_[0]->is_valid(0);
48             }
49              
50             sub sysread {
51 3     3 0 7 my $self = shift;
52 3 50       128 $self->is_valid
53             or $! = ECONNRESET,
54             return; ## no critic (RequireLocalizedPunctuationVars)
55              
56 3         30 my $buffer;
57 3         19 my $seconds = $self->in_timeout;
58              
59 3         8 my $result = eval {
60 3     1   64 local $SIG{'ALRM'} = sub { croak 'Timeout !' };
  1         59  
61 3         20 alarm($seconds);
62              
63 3         47 my $readed = $self->socket->sysread(@_);
64              
65 3         500320 alarm(0);
66              
67 2         8 $buffer = $_[0]; # NECESSARY, timeout does not map the alias @_ !!
68 2         59 $readed;
69             };
70 3 100       1954 if ($@) {
71 1         8 $self->clean();
72 1         41 $! = ETIMEDOUT; ## no critic (RequireLocalizedPunctuationVars)
73             }
74             else {
75 2         71 $_[0] = $buffer;
76             }
77              
78 3         19 $result;
79             }
80              
81             sub syswrite {
82 3     3 0 5 my $self = shift;
83 3 100       66 $self->is_valid
84             or $! = ECONNRESET,
85             return; ## no critic (RequireLocalizedPunctuationVars)
86              
87 2         745 my $seconds = $self->out_timeout;
88 2         4 my $result = eval {
89 2     0   111 local $SIG{'ALRM'} = sub { croak 'Timeout !' };
  0         0  
90 2         28 alarm($seconds);
91              
92 2         87 my $readed = $self->socket->syswrite(@_);
93              
94 2         179 alarm(0);
95              
96 2         26 $readed;
97             };
98 2 50       8 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             =encoding UTF-8
112              
113             =head1 NAME
114              
115             Riak::Light::Timeout::Alarm - proxy to read/write using Alarm as a timeout provider ( Not Safe: can clobber previous alarm )
116              
117             =head1 VERSION
118              
119             version 0.10
120              
121             =head1 DESCRIPTION
122              
123             Internal class
124              
125             =head1 AUTHORS
126              
127             =over 4
128              
129             =item *
130              
131             Tiago Peczenyj
132              
133             =item *
134              
135             Damien Krotkine
136              
137             =back
138              
139             =head1 COPYRIGHT AND LICENSE
140              
141             This software is copyright (c) 2013 by Weborama.
142              
143             This is free software; you can redistribute it and/or modify it under
144             the same terms as the Perl 5 programming language system itself.
145              
146             =cut
147              
148              
149             __END__