App-Chart
view release on metacpan or search on metacpan
lib/App/Chart/Gtk2/Subprocess.pm view on Meta::CPAN
return $pidobj && $pidobj->pid;
}
sub message {
my ($self, $str) = @_;
if (my $job = $self->{'job'}) {
$job->message ($str);
} else {
print $str;
}
}
sub start_job {
my ($self, $job) = @_;
### Subprocess start_job(): "$job"
{
my $freezer = Glib::Ex::FreezeNotify->new ($self, $job);
$job->set (subprocess => $self);
$self->set (job => $job);
my $fh = $self->{'sock'};
if ($fh) {
$job->set(status => __('Starting'));
$self->set (status => __x('Running job: {name}',
name => $job->get('name')));
undef $freezer;
require Storable;
my $data = Storable::freeze ($job->get('args'));
print $fh length($data),"\n",$data;
$fh->flush;
} else {
_unset_job ($self, $self->{'status'}, $self->{'status'});
}
}
}
sub status {
my ($self) = @_;
return $self->{'status'};
}
# return an idle Subprocess, possibly newly started, or undef if the
# subprocess maximum has been reached
#
sub find_idle {
my ($class) = @_;
### Subprocess find_idle()
my @procs = grep { $_->pid }
Gtk2::Ex::TreeModelBits::column_contents ($store, 0);
if (my $proc = List::Util::first {$_->{'sock'} && ! $_->{'job'}} @procs) {
return $proc;
}
if (@procs >= MAX_RUNNING) {
return undef;
}
return $class->new;
}
sub _unset_job {
my ($self, $job_status, $self_status) = @_;
# freeze_notify so job and subprocess are both updated before
# status-change stuff runs
my $freezer = Glib::Ex::FreezeNotify->new ($self);
if (my $job = $self->{'job'}) {
$freezer->add ($job);
$job->set (subprocess => undef,
done => 1,
status => $job_status);
}
$self->set (job => undef,
status => $self_status);
}
sub stop {
my ($self) = @_;
### Subprocess stop()
delete $self->{'io_watch'};
delete $self->{'sock'};
delete $self->{'pidobj'};
_unset_job ($self, undef, __('Stopped'));
}
sub _do_read {
my ($fd, $conditions, $ref_weak_self) = @_;
my $self = $$ref_weak_self || return Glib::SOURCE_REMOVE;
#### Subprocess read: "$self"
my $sock = $self->{'sock'};
my $status = undef;
for (;;) {
my $buf;
my $len = $sock->sysread ($buf, 8192);
#### got: $len
### $!
if (! $len) {
if (! defined $len) {
if ($! == EWOULDBLOCK) { last; } # no more data for now
my $errmsg = Glib::strerror ($!);
$self->message ("Subprocess read error: $errmsg\n");
$status = __('Read error');
} else {
# end of file, child closed pipe
$status = __('Died');
}
delete $self->{'io_watch'};
delete $self->{'sock'};
delete $self->{'pidobj'};
_unset_job ($self, $status, $status);
return Glib::SOURCE_REMOVE;
}
my ($new_status, $message) = $self->{'status_parser'}->parse($buf);
$self->message ($message);
if (defined $new_status) { $status = $new_status; }
}
if (defined $status) {
if ($status eq 'Idle') {
_unset_job ($self, __('Done'), __('Idle'));
App::Chart::Gtk2::JobQueue->consider_run;
( run in 0.550 second using v1.01-cache-2.11-cpan-39bf76dae61 )