{ my @alarm_times; sub myalarm { my $new_alarm = shift; if (defined $new_alarm) { if ($new_alarm) { push @alarm_times, time + $new_alarm; @alarm_times = sort { $a <=> $b} @alarm_times; } else { @alarm_times = (); } } while (my $t = shift @alarm_times) { next if $t < time; alarm($t - time); return; } alarm(0); } ... myalarm(10); # add alarm 10 seconds in future myalarm(0); # cancel all alarms myalarm; # set up next alarm after one triggers