Perl 5.8.0, IO::Socket::INET, $SIG{ALRM} 
Author Message
 Perl 5.8.0, IO::Socket::INET, $SIG{ALRM}

I have a long-running process that occasionally receives a UDP packet:

    $sock = IO::Socket::INET->new( LocalPort => $port, Proto => 'udp', Reuse
=> 1 );

   while ( $sock->recv( $msg, $msgsize ) )  {

       # do stuff with $msg

     ....

   }

  warn "socket closed: $!";

At the same time, I have an alarm clock set up to do some more stuff
periodically:

   $SIG{ALRM} = \&do_other_stuff;

   alarm( $interval );

In Perl 5.6.1, the 'warn' never executed.  In 5.8.0, after the

set. I expected at least an 'interrupted system call'.  What's going on?

I'm ruining SunOS 5.8, gcc 2.95.3



Sat, 29 Jan 2005 03:10:29 GMT  
 Perl 5.8.0, IO::Socket::INET, $SIG{ALRM}

[snip]

Quote:

> In Perl 5.6.1, the 'warn' never executed.  In 5.8.0, after the

> set. I expected at least an 'interrupted system call'.  What's going on?

> I'm ruining SunOS 5.8, gcc 2.95.3

I never got alarm() to work with recv(). A trace of the running process
shows that it does indeed get the SIGALRM, but the recv() call errors
with ERESTART rather than EINTR, thus the recv() call simply restarts.

The workaround is to use select() with a timeout on the socket. select()
tells you if there is data on a file descriptor, and can be set to block
for a specified amount of time, returning (I think, don't quote me)
undef if it times out without receiving anything.

Take a look at the entry for select() in the perlfunc manpage. Also look
at the perlipc manpage. I think there's an example of using select() in
there. I did do this on some code myself in Solaris 8 under Perl 5.6.1,
but at work and I'm at home at the moment. I can post a code snippet
tomorrow if you can't find the info in the docs.

Pete



Sat, 29 Jan 2005 07:15:40 GMT  
 Perl 5.8.0, IO::Socket::INET, $SIG{ALRM}
On Mon, 12 Aug 2002 23:15:40 GMT, Peter J. Stewart

Quote:


> [snip]

>> In Perl 5.6.1, the 'warn' never executed.  In 5.8.0, after the

>> set. I expected at least an 'interrupted system call'.  What's going on?

>> I'm ruining SunOS 5.8, gcc 2.95.3

> I never got alarm() to work with recv(). A trace of the running process
> shows that it does indeed get the SIGALRM, but the recv() call errors
> with ERESTART rather than EINTR, thus the recv() call simply restarts.

That's because SA_RESTART was specified in the sigset struct upon call
to sigaction(2).  

Quote:
> The workaround is to use select() with a timeout on the socket. select()
> tells you if there is data on a file descriptor, and can be set to block
> for a specified amount of time, returning (I think, don't quote me)
> undef if it times out without receiving anything.

Okay, but you can handle SIGALRM, if you use the POSIX module's
interface to sigaction(2) and *not* set SA_RESTART.  

    [untested]

    #!/usr/local/bin/perl
    use warnings;
    use strict;
    use POSIX;

    my $sigset = POSIX::SigSet->new();
    my $action = POSIX::SigAction->new('handler', $sigset, 0);
    sigaction(SIGALRM, $action);

    sub handler {
        # handle a time-out
    }

--
Garry Williams



Sun, 30 Jan 2005 22:49:23 GMT  
 Perl 5.8.0, IO::Socket::INET, $SIG{ALRM}

Quote:

> On Mon, 12 Aug 2002 23:15:40 GMT, Peter J. Stewart

>>The workaround is to use select() with a timeout on the socket. select()
>>tells you if there is data on a file descriptor, and can be set to block
>>for a specified amount of time, returning (I think, don't quote me)
>>undef if it times out without receiving anything.

> Okay, but you can handle SIGALRM, if you use the POSIX module's
> interface to sigaction(2) and *not* set SA_RESTART.  

Thanks for the info, I'll remember this next time I have a similar
coding situation. Just curious though ... would this approach be
portable? I know the POSIX module is supposed to support a standard, but
various OS'es ideas of the standard differ. I thought I remembered
reading that sigaction() was not necessarily implemented on all platforms.

Pete



Mon, 31 Jan 2005 07:55:29 GMT  
 Perl 5.8.0, IO::Socket::INET, $SIG{ALRM}
On Wed, 14 Aug 2002 23:55:29 GMT, Peter J. Stewart

Quote:


>> On Mon, 12 Aug 2002 23:15:40 GMT, Peter J. Stewart

>> Okay, but you can handle SIGALRM, if you use the POSIX module's
>> interface to sigaction(2) and *not* set SA_RESTART.  

> Thanks for the info, I'll remember this next time I have a similar
> coding situation. Just curious though ... would this approach be
> portable?

See perlport, "System Interaction":

     Don't count on signals or %SIG for anything.

--
Garry Williams



Wed, 02 Feb 2005 23:30:48 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. IO::Socket::INET and $SIG{'ALRM'}

2. Proper way to close an IO::Socket or IO::Socket::INET

3. IO::Socket::INET - reading from a socket?

4. IO::Socket::INET - error 10048 - can't bind to socket

5. IO::Socket::INET - Timeout for Reading or a Methode to get the Socket Status back

6. Perl for VMS - use IO::Socket::INET

7. IO::Socket::INET prob?

8. bug in IO::Socket::INET::connect (perl5.004_04)

9. I/O on Win32, using: IO::Socket::INET

10. IO::Socket::INET and fcntl()?

11. Simple TCP client using io::socket::inet not so simple

12. Help With IO::Socket::INET

 

 
Powered by phpBB® Forum Software