main.pl <- B.pm <- A.pm #### # normal run, will finish after 7 iterations # 'ipcs -a' shows everything was cleaned up properly perl main.pl 2 2 # another normal run, but this time hit CTRL-C before the last iter # `ipcs -a` shows SIGINT handler properly cleans up perl main.pl 2 2 # hit CTRL-C # send in 1 as the first param to have B.pm die() after 5 iters # 'ipcs -a' shows everything cleaned up properly perl main.pl 1 1 # PROBLEMATIC RUN # send in three args which will die() main.pl # 'ipcs -a' shows a leak of a memory segment perl main.pl 2 2 2 #### use strict; use warnings; package A; use base 'Exporter'; our @EXPORT = qw(%hash); use IPC::Shareable; $SIG{INT} = sub { print "package A has caught the INT signal\n"; IPC::Shareable->clean_up_all; exit; }; $SIG{__DIE__} = sub { print "package A has caught the die() signal\n"; IPC::Shareable->clean_up_all; exit; }; our %hash; my $tied; BEGIN { $tied = tie %hash, 'IPC::Shareable', { key => 'test', create => 1 }; } END { IPC::Shareable->clean_up_all; } sub run { print "A: "; print "a: $hash{a}, a: $hash{b}\n"; } 1; #### use warnings; use strict; package B; use lib '.'; use A; our %hash; my $count = 0; sub run { my ($self, $x, $y) = @_; $hash{a} = $x; $hash{b} = $y; while (1){ print "B: "; print "a: $hash{a}, b: $hash{b}\n"; A->run; die "whoops!" if $count == 4 && $x == 1; last if $count == 6; $count++; sleep 1; } } 1; #### use warnings; use strict; use lib '.'; use B; print "\nneed 2 (or 3 if die()) args...\n" and exit if @ARGV < 2; print "procID: $$\n"; if (defined $ARGV[2]){ die "main script has died"; } B->run(@ARGV);