File Coverage

blib/lib/Term/YAP/Process.pm
Criterion Covered Total %
statement 27 28 96.4
branch 2 4 50.0
condition 1 3 33.3
subroutine 8 8 100.0
pod n/a
total 38 43 88.3


line stmt bran cond sub pod time code
1             package Term::YAP::Process;
2 7     7   558411 use strict;
  7         21  
  7         215  
3 7     7   41 use warnings;
  7         8  
  7         237  
4 7     7   3974 use Types::Standard 1.000005 qw(Int Bool);
  7         537855  
  7         90  
5 7     7   7611 use Config;
  7         15  
  7         341  
6 7     7   49 use Carp qw(confess);
  7         20  
  7         401  
7 7     7   3640 use Moo 2.000002;
  7         97328  
  7         66  
8 7     7   41038 use namespace::clean 0.26;
  7         45407  
  7         44  
9             extends 'Term::YAP';
10             our $VERSION = '0.08'; # VERSION
11              
12             =head1 NAME
13              
14             Term::YAP::Process - process based subclass of Term::YAP
15              
16             =cut
17              
18             =head1 SYNOPSIS
19              
20             See parent class.
21              
22             =head1 DESCRIPTION
23              
24             This module is a C<fork> base implementation of L<Term::YAP>.
25              
26             =head1 ATTRIBUTES
27              
28             All from parent class plus the described below.
29              
30             =head2 child_pid
31              
32             The PID from the child process created to start the pulse.
33              
34             This is a read-only attribute and it's value is set after invoking the C<start> method.
35              
36             =cut
37              
38             has child_pid => (
39             is => 'ro',
40             isa => Int,
41             reader => 'get_child_pid',
42             writer => '_set_child_pid',
43             clearer => 1
44             );
45              
46             =head2 usr1
47              
48             This class uses a USR1 signal to stop the child process of printing the pulse bar.
49              
50             This read-only attribute holds the signal number (an integer) that is built during class instantiation depending
51             on the platform where is executed.
52              
53             =cut
54              
55             has usr1 => (
56             is => 'ro',
57             isa => Int,
58             reader => 'get_usr1',
59             writer => '_set_usr1',
60             builder => \&_define_signal
61             );
62              
63             =head2 enough
64              
65             This read-only attribute is a boolean used by the child process to check if it should stop printing the pulse bar.
66              
67             You probably won't need to use externally this attribute.
68              
69             =cut
70              
71             has enough => (
72             is => 'ro',
73             isa => Bool,
74             default => 0,
75             reader => 'is_enough',
76             writer => '_set_enough'
77             );
78              
79             has parent => (
80             is => 'ro',
81             isa => Int,
82             default => 0,
83             reader => 'is_parent',
84             writer => '_set_parent'
85             );
86              
87             =head1 METHODS
88              
89             Some parent methods are overriden:
90              
91             =over
92              
93             =item *
94              
95             start
96              
97             =item *
98              
99             stop
100              
101             =back
102              
103             And some others are implemented by this class.
104              
105             =head2 is_enough
106              
107             Getter for C<enough> attribute.
108              
109             =head2 get_usr1
110              
111             Returns the value of C<usr1> attribute.
112              
113             =head2 get_child_pid
114              
115             Returns the value of the C<child_pid> attribute.
116              
117             =head2 is_parent
118              
119             Getter for C<parent> attribute.
120              
121             =head2 start
122              
123             Method overrided from parent class.
124              
125             This method will use C<fork> to create a child process to create the pulse bar.
126              
127             The child process will have a signal handler for the USR1 signal to stop the pulse bar.
128              
129             =cut
130              
131             around start => sub {
132              
133             my ( $orig, $self ) = ( shift, shift );
134              
135             if ( $self->is_parent() and $self->get_child_pid() ) {
136              
137             confess "no fork() before stopping " . $self->get_child_pid();
138              
139             }
140              
141             my $child_pid = fork();
142              
143             if ($child_pid) {
144              
145             #parent
146             print "I'm a parent: $$\n" if ( $self->is_debug );
147             $self->_set_child_pid($child_pid);
148             $self->_set_running(1);
149             $self->_set_parent(1);
150             print "$$ forked ", $self->get_child_pid, "\n" if ( $self->is_debug );
151             $self->$orig;
152              
153             }
154             else {
155             #child
156             print "I'm a child: $$\n" if ( $self->is_debug );
157             $SIG{USR1} = sub {
158             $self->_set_enough(1);
159             };
160             $self->_keep_pulsing();
161             exit 0;
162              
163             }
164              
165             };
166              
167             sub _define_signal {
168              
169 6     6   858 my %sig_num;
170 6 50 33     912 unless ( $Config{sig_name} && $Config{sig_num} ) {
171 0           confess "No sigs?";
172             }
173             else {
174 6         174 my @names = split ' ', $Config{sig_name};
175 6         354 @sig_num{@names} = split ' ', $Config{sig_num};
176              
177             confess("this platform does not include USR1 signal")
178 6 50       48 unless ( exists( $sig_num{USR1} ) );
179              
180 6         210 return $sig_num{USR1};
181              
182             }
183              
184             }
185              
186             =head2 stop
187              
188             Method overrided from parent class.
189              
190             This method will send a USR1 signal with C<kill> to the child process executing the
191             pulse bar.
192              
193             The child process termination will be handled with C<waitpid>.
194              
195             =cut
196              
197             around stop => sub {
198              
199             my ( $orig, $self ) = ( shift, shift );
200              
201             #if not the parent, get out
202             if ( $self->is_parent() ) {
203              
204             # :WORKAROUND:11/21/2015 07:33:13 PM:: don't know why, this is being called more than once, thus checking if child_pid is defined to avoid errors
205             if ( $self->get_child_pid ) {
206              
207             print "$$ preparing to kill ", $self->get_child_pid, "\n"
208             if ( $self->is_debug() );
209             my $count = kill $self->get_usr1(), $self->get_child_pid();
210             if ( $self->is_debug() ) {
211             print "shit, child didn't receive the signal: $count\n"
212             unless ( $count == 1 );
213             }
214             $self->_sleep();
215             my $pid = waitpid( $self->get_child_pid(), 0 );
216             if ( $self->is_debug ) {
217             if ( $pid == -1 ) {
218             print "we got a problem\n";
219             }
220             else {
221             print "child $pid is gone\n";
222             }
223             }
224             $self->clear_child_pid();
225              
226             }
227              
228             }
229             $self->$orig();
230              
231             };
232              
233             around _is_enough => sub {
234              
235             my ( $orig, $self ) = ( shift, shift );
236             return $self->is_enough();
237              
238             };
239              
240             =head1 SEE ALSO
241              
242             =over
243              
244             =item *
245              
246             L<Term::Pulse>
247              
248             =item *
249              
250             L<Term::YAP::iThread>
251              
252             =item *
253              
254             L<Moo>
255              
256             =back
257              
258             =head1 AUTHOR
259              
260             Alceu Rodrigues de Freitas Junior, E<lt>arfreitas@cpan.orgE<gt>
261              
262             L<Term::Pulse> was originally created by Yen-Liang Chen, E<lt>alec at cpan.comE<gt>
263              
264             =head1 COPYRIGHT AND LICENSE
265              
266             This software is copyright (c) 2012 of Alceu Rodrigues de Freitas Junior, E<lt>arfreitas@cpan.orgE<gt>
267              
268             This file is part of Siebel Monitoring Tools.
269              
270             Siebel Monitoring Tools is free software: you can redistribute it and/or modify
271             it under the terms of the GNU General Public License as published by
272             the Free Software Foundation, either version 3 of the License, or
273             (at your option) any later version.
274              
275             Siebel Monitoring Tools is distributed in the hope that it will be useful,
276             but WITHOUT ANY WARRANTY; without even the implied warranty of
277             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
278             GNU General Public License for more details.
279              
280             You should have received a copy of the GNU General Public License
281             along with Siebel Monitoring Tools. If not, see <http://www.gnu.org/licenses/>.
282              
283             =cut
284              
285             1;