#!/usr/bin/perl use strict; use warnings; use autodie qw( open close ); use Fcntl qw( LOCK_EX LOCK_UN ); sub say { print scalar localtime(),' pid=',$$,': ',@_,"\n"; } my $mainpid=$$; my $pid=fork() // die "Can't fork: $!"; # in both parent and child process, install signal handler $SIG{'ALRM'}=sub { warn 'SIGALRM in ',$$==$mainpid ? 'main' : 'helper' }; if ($pid) { # parent process say "main starts"; say "main waiting for helper to lock"; sleep 1; open my $f,'>','tempfile.tmp'; alarm(5); say "main flock"; flock($f,LOCK_EX) or say "main can't lock: $! (error code ",0+$!,')'; say "main flock done"; alarm(0); close $f; say "main ends"; wait; } else { # child process say "helper starts"; open my $f,'>','tempfile.tmp'; flock($f,LOCK_EX) or die "Helper can't lock: $!"; select(undef,undef,undef,10); flock($f,LOCK_UN) or die "Helper can't unlock: $!"; close $f; say "helper ends"; exit(0); } #### >env - perl interrupted.pl Sun May 24 20:24:11 2015 pid=31389: main starts Sun May 24 20:24:11 2015 pid=31389: main waiting for helper to lock Sun May 24 20:24:11 2015 pid=31390: helper starts Sun May 24 20:24:12 2015 pid=31389: main flock SIGALRM in main at interrupted.pl line 16. Sun May 24 20:24:17 2015 pid=31389: main can't lock: Interrupted system call (error code 4) Sun May 24 20:24:17 2015 pid=31389: main flock done Sun May 24 20:24:17 2015 pid=31389: main ends Sun May 24 20:24:21 2015 pid=31390: helper ends >env - PERL_SIGNALS=unsafe perl interrupted.pl Sun May 24 20:24:39 2015 pid=31396: main starts Sun May 24 20:24:39 2015 pid=31396: main waiting for helper to lock Sun May 24 20:24:39 2015 pid=31397: helper starts Sun May 24 20:24:40 2015 pid=31396: main flock SIGALRM in main at interrupted.pl line 16. Sun May 24 20:24:49 2015 pid=31397: helper ends Sun May 24 20:24:49 2015 pid=31396: main flock done Sun May 24 20:24:49 2015 pid=31396: main ends alex@enterprise pts/0 20:24:49 /home/alex/tmp/lockdemo> #### >env - PERL_SIGNALS=unsafe strace -o trace.txt /usr/bin/perl interrupted.pl Sun May 24 20:39:02 2015 pid=31774: helper starts Sun May 24 20:39:02 2015 pid=31773: main starts Sun May 24 20:39:02 2015 pid=31773: main waiting for helper to lock Sun May 24 20:39:03 2015 pid=31773: main flock SIGALRM in main at interrupted.pl line 16. Sun May 24 20:39:12 2015 pid=31774: helper ends Sun May 24 20:39:12 2015 pid=31773: main flock done Sun May 24 20:39:12 2015 pid=31773: main ends >grep -C5 flock trace.txt fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 alarm(5) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 write(1, "Sun May 24 20:39:03 2015 pid=317"..., 47) = 47 flock(3, LOCK_EX) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) --- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} --- rt_sigaction(SIGALRM, NULL, {0x7fdcf683dde0, [], SA_RESTORER|SA_RESTART, 0x7fdcf5a2f670}, 8) = 0 write(2, "SIGALRM in main at interrupted.p"..., 43) = 43 rt_sigreturn() = 73 flock(3, LOCK_EX) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 write(1, "Sun May 24 20:39:12 2015 pid=317"..., 52) = 52 alarm(0) = 0 close(3) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 >env - strace -o trace.txt /usr/bin/perl interrupted.pl Sun May 24 20:43:14 2015 pid=31859: helper starts Sun May 24 20:43:14 2015 pid=31858: main starts Sun May 24 20:43:14 2015 pid=31858: main waiting for helper to lock Sun May 24 20:43:15 2015 pid=31858: main flock SIGALRM in main at interrupted.pl line 16. Sun May 24 20:43:20 2015 pid=31858: main can't lock: Interrupted system call (error code 4) Sun May 24 20:43:20 2015 pid=31858: main flock done Sun May 24 20:43:20 2015 pid=31858: main ends Sun May 24 20:43:24 2015 pid=31859: helper ends >grep -C5 flock trace.txt fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 alarm(5) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 write(1, "Sun May 24 20:43:15 2015 pid=318"..., 47) = 47 flock(3, LOCK_EX) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) --- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} --- rt_sigreturn() = -1 EINTR (Interrupted system call) rt_sigprocmask(SIG_BLOCK, [ALRM], [], 8) = 0 rt_sigaction(SIGALRM, NULL, {0x7f43b0eaede0, [], SA_RESTORER, 0x7f43b00a0670}, 8) = 0 write(2, "SIGALRM in main at interrupted.p"..., 43) = 43 > #### >env - PERL_SIGNALS=unsafe strace -o trace.txt /usr/bin/perl interrupted.pl Sun May 24 20:51:14 2015 pid=32083: helper starts Sun May 24 20:51:14 2015 pid=32082: main starts Sun May 24 20:51:14 2015 pid=32082: main waiting for helper to lock Sun May 24 20:51:15 2015 pid=32082: main flock SIGALRM in main at interrupted.pl line 16. Sun May 24 20:51:24 2015 pid=32083: helper ends Sun May 24 20:51:24 2015 pid=32082: main flock done Sun May 24 20:51:24 2015 pid=32082: main ends >grep -C5 SIGALRM trace.txt close(3) = 0 rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fdbc5fc2a10) = 32083 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 rt_sigprocmask(SIG_BLOCK, [ALRM], [], 8) = 0 rt_sigaction(SIGALRM, {0x7fdbc5ad9de0, [], SA_RESTORER|SA_RESTART, 0x7fdbc4ccb670}, {SIG_DFL, [], 0}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 fstat(3, {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdbc5fe6000 -- fcntl(3, F_SETFD, FD_CLOEXEC) = 0 alarm(5) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 write(1, "Sun May 24 20:51:15 2015 pid=320"..., 47) = 47 flock(3, LOCK_EX) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) --- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} --- rt_sigaction(SIGALRM, NULL, {0x7fdbc5ad9de0, [], SA_RESTORER|SA_RESTART, 0x7fdbc4ccb670}, 8) = 0 write(2, "SIGALRM in main at interrupted.p"..., 43) = 43 rt_sigreturn() = 73 flock(3, LOCK_EX) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 write(1, "Sun May 24 20:51:24 2015 pid=320"..., 52) = 52 alarm(0) = 0 -- rt_sigaction(SIGKILL, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGUSR1, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGSEGV, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGUSR2, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGPIPE, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGALRM, NULL, {0x7fdbc5ad9de0, [], SA_RESTORER|SA_RESTART, 0x7fdbc4ccb670}, 8) = 0 rt_sigaction(SIGALRM, {SIG_DFL, [], SA_RESTORER|SA_RESTART, 0x7fdbc4ccb670}, {0x7fdbc5ad9de0, [], SA_RESTORER|SA_RESTART, 0x7fdbc4ccb670}, 8) = 0 rt_sigaction(SIGTERM, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGSTKFLT, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGCONT, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGSTOP, NULL, {SIG_DFL, [], 0}, 8) = 0 >env - strace -o trace.txt /usr/bin/perl interrupted.pl Sun May 24 20:51:35 2015 pid=32103: helper starts Sun May 24 20:51:35 2015 pid=32102: main starts Sun May 24 20:51:35 2015 pid=32102: main waiting for helper to lock Sun May 24 20:51:36 2015 pid=32102: main flock SIGALRM in main at interrupted.pl line 16. Sun May 24 20:51:41 2015 pid=32102: main can't lock: Interrupted system call (error code 4) Sun May 24 20:51:41 2015 pid=32102: main flock done Sun May 24 20:51:41 2015 pid=32102: main ends Sun May 24 20:51:45 2015 pid=32103: helper ends >grep -C5 SIGALRM trace.txt close(3) = 0 rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f45f31f1a10) = 32103 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 rt_sigprocmask(SIG_BLOCK, [ALRM], [], 8) = 0 rt_sigaction(SIGALRM, {0x7f45f2d08de0, [], SA_RESTORER, 0x7f45f1efa670}, {SIG_DFL, [], 0}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 fstat(3, {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f45f3215000 -- fcntl(3, F_SETFD, FD_CLOEXEC) = 0 alarm(5) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 write(1, "Sun May 24 20:51:36 2015 pid=321"..., 47) = 47 flock(3, LOCK_EX) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) --- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} --- rt_sigreturn() = -1 EINTR (Interrupted system call) rt_sigprocmask(SIG_BLOCK, [ALRM], [], 8) = 0 rt_sigaction(SIGALRM, NULL, {0x7f45f2d08de0, [], SA_RESTORER, 0x7f45f1efa670}, 8) = 0 write(2, "SIGALRM in main at interrupted.p"..., 43) = 43 rt_sigprocmask(SIG_UNBLOCK, [ALRM], NULL, 8) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 write(1, "Sun May 24 20:51:41 2015 pid=321"..., 92) = 92 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2335, ...}) = 0 write(1, "Sun May 24 20:51:41 2015 pid=321"..., 52) = 52 -- rt_sigaction(SIGKILL, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGUSR1, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGSEGV, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGUSR2, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGPIPE, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGALRM, NULL, {0x7f45f2d08de0, [], SA_RESTORER, 0x7f45f1efa670}, 8) = 0 rt_sigaction(SIGALRM, {SIG_DFL, [], SA_RESTORER, 0x7f45f1efa670}, {0x7f45f2d08de0, [], SA_RESTORER, 0x7f45f1efa670}, 8) = 0 rt_sigaction(SIGTERM, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGSTKFLT, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGCONT, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGSTOP, NULL, {SIG_DFL, [], 0}, 8) = 0 > #### #ifdef SA_RESTART if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG) act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */ #endif