Subject: | Tcl doesn't play nicely with forking |
If an app using Tcl forks, the childs don't exit because Tcl::_Finalize
is called in the END block.
This little script demonstrates the problem:
#!/usr/bin/env perl
use strict;
use warnings;
use Parallel::Runner;
use Tcl;
#print "before finalize";
# that goes forward in time and kills $tcl before it even exists
#Tcl::_Finalize;
#print "after finalize";
my $tcl = Tcl->new;
$tcl->Eval("puts {before the fork}");
my $runner = Parallel::Runner->new(2);
$runner->run( sub {
$tcl->Eval("puts {child $_}");
#POSIX::_exit(0); # this is one of the possible workarounds
} ) for 1..3;
$runner->finish;
mst and Exodist helped me figure out what's going on and suggested the
following fix:
add this to the top of Tcl.pm:
my $pid = $$;
change the END block to:
END {
Tcl::_Finalize()
if $$ == $pid;
}