Great Circle Associates Majordomo-Workers
(May 1998)
 

Indexed By Date: [Previous] [Next] Indexed By Thread: [Previous] [Next]

Subject: Re: Problem with Majordomo 2.0 installation
From: Jason L Tibbitts III <tibbs @ hpc . uh . edu>
Date: 09 May 1998 01:46:10 -0500
To: majordomo-workers @ greatcircle . com, rms39 @ columbia . edu (Russell Steinthal)
In-reply-to: rms39@columbia.edu's message of "Fri, 08 May 1998 11:27:19 -0300"
References: <199805081527.LAA21828@condor.ec.rhno.columbia.edu>

>>>>> "RS" == Russell Steinthal <rms39@columbia.edu> writes:

RS> We're probably nearing the limits of my socket programming knowledge,

No problem; I just expanded mine a bit.  The moral: when the Camel says not
to mix select and buffered reads unless you really know what you're doing,
and you don't really know what you're doing, you should heed the warning.
The problem is, of course, that the getline call reads a lot more than one
line and stuffs the rest in a buffer somewhere.  Then the next select call
comes up and it fails because there's nothing left to read from the socket.
It's all in the buffer...

Thankfully everything's OO down there, so I can make one localized change
and everything else should fall into place.

Please try this patch on for size:

Index: lib/Mj/Deliver/Connection.pm
--- Connection.pm       1998/03/27 04:42:00     1.1.1.1
+++ Connection.pm       1998/05/09 06:38:30
@@ -13,6 +13,10 @@
 the same interface.  An earlier version of this code supported executing a
 program with the Connection object encapsulating its input and output.
 
+This class also encapsulates a simple buffered IO mechanism over unbuffered
+sysread and syswrite.  This enables us to use select calls to provide real
+timeouts on socket reads.  (The buffered writes are still used, right now.)
+
 =cut
 
 package Mj::Deliver::Connection;
@@ -47,6 +51,7 @@
   return undef unless $self->{'outhandle'};
   $self->{'outhandle'}->autoflush(1);
   $self->{'outsel'} = new IO::Select $self->{'outhandle'};
+  $self->{buffer} = '';
   return $self;
 }
 
@@ -68,6 +73,10 @@
 This grabs a line from the connection, timing out (and returning undef)
 appropriately.
 
+Because select and getline (and buffered input in general) don''t mix, we
+maintain our own buffer and read a chunk off of the socket whenever it is
+necessary.
+
 There was support for a separate input handle, but the support for
 communicating with a pair of filehandles has been scrapped.  (That was the
 original reason for this module, but...)
@@ -75,8 +84,16 @@
 =cut
 sub getline {
   my $self = shift;
-  return undef unless $self->{'outsel'}->can_read($self->{'timeout'});
-  $self->{'outhandle'}->getline;
+  my ($len);
+  
+  while(!length($self->{buffer}) || $self->{buffer} !~ /\n/) {
+    return undef unless $self->{outsel}->can_read($self->{timeout});
+    $len = $self->{outhandle}->sysread($self->{buffer}, 1024,
+                                      length($self->{buffer}));
+    return undef unless $len;
+  }
+  $self->{buffer} =~ s/^([^\n]*\n)//;
+  $1;
 }
 
 =head2 fileno

 - J<


Follow-Ups:
References:
Indexed By Date Previous: Re: Problem with Majordomo 2.0 installation
From: Jason L Tibbitts III <tibbs@hpc.uh.edu>
Next: Request for 'commands' in the aliases/addresses
From: Brock Rozen <brozen@torah.org>
Indexed By Thread Previous: Re: Problem with Majordomo 2.0 installation
From: rms39@columbia.edu (Russell Steinthal)
Next: Re: Problem with Majordomo 2.0 installation
From: rms39@columbia.edu (Russell Steinthal)

Google
 
Search Internet Search www.greatcircle.com