PEPPLER.ORG
Michael Peppler
Sybase Consulting
Menu
Home
Sybase on Linux
Install Guide for Sybase on Linux
General Sybase Resources
General Perl Resources
Freeware
Sybperl
Sybase::Simple
DBD::Sybase
BCP Tool
Bug Tracker
Mailing List Archive
Downloads Directory
FAQs
Sybase on Linux FAQ
Sybperl FAQ
Personal
Michael Peppler's resume

sybperl-l Archive

Up    Prev    Next    

From: Tim_Green at mercer dot com
Subject: Re[2]: Off-topic: Perl Question
Date: Jan 15 1998 3:26PM

>Tim_Green@mercer.com wrote:
>>      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
>>      condition?
>
>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 
     without Sybperl.
     
     Tim