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 )