File Coverage

backend/driver.pm
Criterion Covered Total %
statement 119 121 98.3
total 119 121 98.3


line stmt code
1   # Copyright 2009-2013 Bernhard M. Wiedemann
2   # Copyright 2012-2021 SUSE LLC
3   # SPDX-License-Identifier: GPL-2.0-or-later
4    
5   # this class is what presents $backend in isotovideo and its code runs
6   # in the main process. But its main task is to start a 2nd process and talk to it over
7   # a PIPE
8   # in that 2nd process runs the actual backend, derived from backend::baseclass
9    
10   use Mojo::Base -base, -signatures;
11 30  
  30  
  30  
12   use autodie ':all';
13 30  
  30  
  30  
14   use Carp 'croak';
15 30 use Mojo::JSON 'to_json';
  30  
  30  
16 30 use File::Path 'remove_tree';
  30  
  30  
17 30 use POSIX '_exit';
  30  
  30  
18 30 require IPC::System::Simple;
  30  
  30  
19   use Mojo::IOLoop::ReadWriteProcess 'process';
20 30 use Mojo::IOLoop::ReadWriteProcess::Session 'session';
  30  
  30  
21 30 use myjsonrpc;
  30  
  30  
22 30 use signalblocker;
  30  
  30  
23 30 use log qw(diag fctinfo);
  30  
  30  
24 30  
  30  
  30  
25   my $self = $class->SUPER::new({class => $class});
26 16  
  16  
  16  
  16  
27 16 require "backend/$name.pm";
28   $self->{backend} = "backend::$name"->new();
29 16 $self->{backend_name} = $name;
30 16  
31 16 session->on(
32   collected_orphan => sub {
33   my ($session, $p) = @_;
34   fctinfo("Driver backend collected unknown process with pid " . $p->pid . " and exit status: " . $p->exit_status);
35 0 });
36 0  
37 16 $self->start();
38    
39 16 return $self;
40   }
41 7  
42   open(my $STDOUTPARENT, '>&', *STDOUT);
43   open(my $STDERRPARENT, '>&', *STDERR);
44 18  
  18  
  18  
45 18 my $backend_process = process(
46 18 sleeptime_during_kill => .1,
47   total_sleeptime_during_kill => 30,
48   max_kill_attempts => 1,
49   kill_sleeptime => 0,
50   blocking_stop => 1,
51   separate_err => 0,
52   subreaper => 1,
53   code => sub {
54   my $process = shift;
55   $0 = "$0: backend";
56    
57 10 open STDOUT, ">&", $STDOUTPARENT;
58 10 open STDERR, ">&", $STDERRPARENT;
59    
60 10 # initialize OpenCV
61 10 my $signal_blocker = signalblocker->new;
62   require cv;
63   cv::init();
64 10 require tinycv;
65 10 tinycv::create_threads();
66 10 undef $signal_blocker;
67 10  
68 10 $self->{backend}->run(fileno($process->channel_in), fileno($process->channel_out));
69 10 });
70    
71 10 $backend_process->on(collected => sub { diag("backend process exited: " . shift->exit_status) });
72 18 $backend_process->start;
73    
74 18 diag("$$: channel_out " . fileno($backend_process->channel_out) . ', channel_in ' . fileno($backend_process->channel_in));
  5  
75 18 $self->{backend_pid} = $backend_process->pid;
76   $self->{backend_process} = $backend_process;
77 8 }
78 8  
79 8  
80   return unless $self->{backend_process}->is_running;
81    
82 2 $self->stop_backend() if $self->{backend_process}->channel_out;
  2  
  2  
  2  
  2  
83   close($self->{backend_process}->channel_out) if $self->{backend_process}->channel_out;
84 4 close($self->{backend_process}->channel_in) if $self->{backend_process}->channel_in;
  4  
  4  
85 4 $self->{backend_process}->channel_in(undef);
86   $self->{backend_process}->channel_out(undef);
87 3 $self->{backend_process}->stop;
88 3 }
89 3  
90 3 # new api
91 3  
92 3 my $json = to_json({backend => $self->{backend_name}});
93   open(my $runf, ">", 'backend.run');
94   print $runf "$json\n";
95   close $runf;
96    
97 6 # remove old screenshots
  6  
  6  
98 6 remove_tree($bmwqemu::screenshotpath);
99 6 mkdir $bmwqemu::screenshotpath;
100 6  
101 6 $self->_send_json({cmd => 'start_vm'}) || die "failed to start VM";
102   return 1;
103   }
104 6  
105 6 $self->_send_json({cmd => 'stop_vm'});
106   # remove if still existent
107 6 unlink('backend.run') if -e 'backend.run';
108 5 return;
109   }
110    
111 4 # new api end
  4  
  4  
112 4  
113    
114 4 # virtual methods end
115 4  
116   croak "no backend running" unless $self->{backend_process}->channel_in;
117   my $token = myjsonrpc::send_json($self->{backend_process}->channel_in, $cmd);
118   my $rsp = myjsonrpc::read_json($self->{backend_process}->channel_out, $token);
119    
120 1 return $rsp->{rsp} if defined $rsp;
  1  
  1  
  1  
  1  
121   # this might have been closed by signal handler
122   no autodie 'close';
123   close($self->{backend_process}->channel_out);
124 99 $self->{backend_process}->channel_out(undef);
  99  
  99  
  99  
125 99 $self->{backend_process}->stop;
126 99 return;
127 99 }
128    
129 99 1;