Re: forked process exiting before output read
- From: "Jeffrey Ratcliffe" <jeffrey ratcliffe gmail com>
- To: muppet <scott asofyet org>
- Cc: gtk-perl-list gnome org
- Subject: Re: forked process exiting before output read
- Date: Fri, 1 Feb 2008 07:26:31 +0100
On 31/01/2008, Jeffrey Ratcliffe <jeffrey ratcliffe gmail com> wrote:
This seems to break for utf8 messages, with:
*** unhandled exception in callback:
*** Wide character in send
I've tried creating the filehandles with
$fh = FileHandle->new(":utf8");
or
binmode $fh, ':utf8';
Here's a demo trying to send/recv a utf8 character. It crashes with:
$ ../ForkDemo8.pl
writing 0 of 4
*** unhandled exception in callback:
*** Wide character in send at ../ForkDemo8.pl line 96.
*** ignoring at ../ForkDemo8.pl line 30.
Thanks for any pointers
Jeff
#!/usr/bin/perl
use warnings;
use strict;
use Socket;
use Gtk2 -init;
use Glib qw(TRUE FALSE); # To get TRUE and FALSE
use FileHandle;
use POSIX;
# Create the windows
my $window = Gtk2::Window->new('toplevel');
my $box = Gtk2::VBox->new;
my $pbar = Gtk2::ProgressBar->new;
my $buttonQuit = Gtk2::Button->new('Quit');
my $buttonStart = Gtk2::Button->new('Start');
$window->add ($box);
$box->add ($pbar);
$box->add($buttonQuit);
$box->add($buttonStart);
my %helperTag;
# We should also link this to the destroy message on the main window,
# this is just quick and dirty
$buttonQuit->signal_connect(clicked => \&on_quit_clicked);
$buttonStart->signal_connect(clicked => \&start_process);
$window->show_all;
Gtk2->main;
# Process the exit of the child. If you were doing something useful,
# you might keep things like information about what data needs
# to be reloaded when a child process exits.
sub sig_child {
my $pid = wait;
if ($pid >= 0) {
delete $helperTag{$pid};
}
}
$SIG{CHLD} = \&sig_child;
sub start_process {
my $pid;
my ($reader, $writer);
$reader = FileHandle->new(":utf8");
$writer = FileHandle->new(":utf8");
socketpair($reader, $writer, AF_UNIX, SOCK_DGRAM, PF_UNSPEC);
$pid = fork();
if ($pid) {
# We're still in the parent, set up to watch the streams:
shutdown($writer, 0);
my $line;
$helperTag{$pid} = Glib::IO->add_watch($reader->fileno(), ['in', 'hup'], sub {
my ($fileno, $condition) = @_;
if ($condition & 'in') { # bit field operation. >= would also work
recv($reader, $line, 1000, 0);
if (defined($line) and $line =~ /(\d*\.?\d*)(.*)/) {
my $fraction=$1;
my $text=$2;
$pbar->set_fraction($fraction);
$pbar->set_text($text);
Gtk2->main_iteration while Gtk2->events_pending;
sleep(2);
}
}
# Can't have elsif here because of the possibility that both in and hup are set.
# Only allow the hup if sure an empty buffer has been read.
if (($condition & 'hup') and (! defined($line) or $line eq '')) { #
bit field operation. >= would also work
return FALSE; # uninstall
}
return TRUE; # continue without uninstalling
});
}
else {
# We're in the child. Do whatever processes we need to. We *must*
# exit this process with POSIX::_exit(...), because exit() would
# "clean up" open file handles, including our display connection,
# and merely returning from this subroutine in a separate process
# would *really* confuse things.
shutdown($reader, 1);
$pid = getpid();
my $n = 4;
for (my $i = 0; $i <= $n; $i++) {
sleep(1);
send($writer, $i/$n."Running \x{2013} $i of $n\n", 0);
}
POSIX::_exit(0);
}
}
# We should clean up after ourselves so that we don't
# leave dead processes flying around.
sub on_quit_clicked {
# 15 = SIGTERM
kill 15, $_ foreach (keys %helperTag);
Gtk2->main_quit;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]