From: A. Farber on
Hello,

I have a non-blocking server:

$SIG{PIPE} = $SIG{ALRM} = $SIG{HUP} = 'IGNORE';
$SIG{USR1} = $SIG{USR2} = sub { $Dump = 1; };
$SIG{TERM} = $SIG{INT} = sub { $Quit = 1; };
......

sub dump {
my $pkg = shift;

print STDERR Dumper(\%Kids);
}

sub loop {
my $pkg = shift;

while (not $Quit) {
if ($Dump) {
$Dump = undef;
Child->dump();
#User->dump();
}

if ($Poll->poll(TIMEOUT) < 0) {
warn "poll error: $!\n";
sleep(TIMEOUT);
next;
}

$pkg->add($httpSocket) if $Poll->events($httpSocket) &
POLLIN;
$pkg->add($tcpSocket) if $Poll->events($tcpSocket) &
POLLIN;

for my $child (values %Kids) {
my $fh = $child->{FH};
my $mask = $Poll->events($fh);

if ($mask & (POLLERR | POLLHUP)) {
$child->remove();
} elsif ($mask & POLLIN) {
$child->remove() unless $child->read
();
} elsif ($mask & POLLOUT) {
$child->remove() unless $child->write
();
}
}
# remove not responding users
User->timeout();
}
}

When I check for poll() return value as above,
then the Child->dump() isn't called when I send
a USR1 signal to my script. I only see:

poll error: Interrupted system call

and the script continues. When I remove the "if",
warn() and sleep() and just call in void context

$Poll->poll(TIMEOUT);

then Child->dump() is called as expected.

Why is it so, why isn't USR1 registered in the 1st case?

Do warn() or sleep() clear %! and how could I workaround this?

Thank you
Alex

PS: I'm using:

This is perl, v5.10.0 built for i386-openbsd