Up Prev Next
From: Tim_Green at mercer dot com
Subject: Re: Off-topic: Perl Question
Date: Jan 15 1998 3:26PM
>> So, I've got couple questions:
>> 1. In the code below extracted from the perlipc man page, can someone
>> explain the relationship between the for loop, the reaper function and
>> the $WAITEDPID variable? Why must $waitedpid be in the for loop's
>I am not a TCP/IP specialist, but I would guess that the loop could be written:
>for ( $waitpid=0
> ($paddr = accept(Client,Server));
> $waitedpid = 0, close Client)
> my($port,$iaddr) = sockaddr_in($paddr);
>ie skip the $waitpid condition in the for(), and forget about the if($waitpid)
>in the body of the loop.
>In my opinion this should work fine.
If I remember correctly (and I might not), I tried this when I
originally wrote the server (with perl 5.003). It didn't work. At
the time I hadn't a clue why, but I've since come to think it's
because the accept() function call will return with an undefined
socket if the application receives a signal. If a child process wakes
up (which signals the REAPER function), no socket is available, $paddr
is undefined and the for loop's condition would fail. The '||
$waitedpid ' keeps this from happening and the
'next if $waitedpid' sets you up to accept a socket again.
But what I don't understand is why the for loop needs to be coupled
with a reference to $waitedpid at all. Why not just a 'while accept()
next if not defined($paddr)' construct? I suppose it might work as I
don't remember all that I tried back then, and I know a little more
now, but I've seen the for() example more than once so I assume there
must be some reason for $waitedpid to be coupled with the for loop,
but I can't figure what.
>> 2. Why does the example code from 5.003 work in 5.003 but not in
>> 5.004? Or why is the change made in the 5.004 example not necessary
>> in 5.003?
>I don't know, but it's may be related to signal handling changes.
That's my opinion as well, though I couldn't find anything documented
specifically in the changes document. My application now receives an extra
child wakeup signal for each legit one, with -1 return statuses from
waitpid() (I use waitpid instead of wait in my REAPER routine). The signal
terminates the accept() call (actually, I'm speaking UDP and using recv(),
though they have similar behavior) and the -1 caused the 'next if
$waitedpid' branch to be taken, effectively throwing away every other
message I received. Adding the check on $paddr as the new man page showed
solved the problem.
Anyway, thanks for the reply. If you're curious what this is all about, I
wrote a server with sybperl to receive messages sent from my Sybase server
using Sybase's syb_sendmsg function. We use it to run unix processes,
eliminating our need for an Open Server application. Couldn't have done it