[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdesdk/scripts
From:       Michael Pyne <michael.pyne () kdemail ! net>
Date:       2007-11-24 4:52:57
Message-ID: 1195879977.787824.1189.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 740765 by mpyne:

apaku uncovered another bug in the pipe() based IPC implemention.  Of course, I
had already foreshadowed it.  For future reference, if you see a comment
somewhere that says "should be enough length", it is not enough length.

Making the read buffer bigger would probably have fixed it, but instead I made
the buffer even smaller and made the I/O handle message fragments instead.  A
nifty exercise is to reduce the 256 in the sysread call to 1 and see if
everything still works in pretend mode. :)

CCMAIL:apaku@gmx.de


 M  +25 -13    kdesvn-build  


--- trunk/KDE/kdesdk/scripts/kdesvn-build #740764:740765
@@ -369,7 +369,10 @@
         my $class = shift;
 
         # Must bless a hash ref since subclasses expect it.
-        return bless {}, $class;
+        my $ref = {};
+        $ref->{'residue'} = ''; # Define this for later.
+
+        return bless $ref, $class;
     }
 
     sub notifyUpdateSuccess
@@ -426,26 +429,35 @@
         my $self = shift;
         my $outBuffer = shift;
 
-        # Check if we still have data left over from last read.
-        if ($self->{'residue'})
+        # Check if we still have data left over from last read, and if it
+        # contains a full message.
+        if ($self->{'residue'} =~ /\n/)
         {
             my ($first, $remainder) = split(/\n/, $self->{'residue'}, 2);
-            $self->{'residue'} = $remainder;
+            $self->{'residue'} = defined $remainder ? $remainder : '';
 
             return unpackMsg($first, $outBuffer);
         }
 
-        my $msg = $self->receiveMessage(@_);
-        return undef if not defined $msg;
+        # Read in messages enough to get to the message separator (\n)
+        my $msg = '';
+        while($msg !~ /\n/) {
+            my $msgFragment = $self->receiveMessage(@_);
+            $msg .= $msgFragment if defined $msgFragment;
 
-        chomp $msg;
+            last unless defined $msgFragment;
+        }
 
-        # If other guy sent a ton of messages we may have a bunch that we
-        # received.  Assume they're separated by newlines.
+        return undef if not defined $msg or $msg eq '';
+
+        # We may have residue still if we had a partial husk of a message, so
+        # append to the residue before breaking up the message.  We assume a
+        # newline separates the messages.
+        $msg = $self->{'residue'} . $msg;
         my ($first, $remainder) = split(/\n/, $msg, 2);
 
         # Save rest for later.
-        $self->{'residue'} = $remainder;
+        $self->{'residue'} = defined $remainder ? $remainder : '';
 
         return unpackMsg($first, $outBuffer);
     }
@@ -579,7 +591,7 @@
         my $value;
 
         undef $!; # Clear error marker
-        my $result = sysread ($self->{$fh}, $value, 512); # Enough length I think.
+        my $result = sysread ($self->{$fh}, $value, 256);
 
         return undef if not $result;
         return $value;
@@ -819,7 +831,7 @@
     return get_log_dir('global') . "/build-log";
 }
 
-# Subroutine to retrieve a subdirecty path for the given module.
+# Subroutine to retrieve a subdirectory path for the given module.
 # First parameter is the name of the module, and the second
 # parameter is the option key (e.g. build-dir or log-dir).
 sub get_subdir_path
@@ -6041,7 +6053,7 @@
 
             # Don't check for $! first, it seems to always be set to EBADF.
             # Probably I'm screwing up the select() call?
-            if ($msg)
+            if (defined $msg)
             {
                 push @msgs, $msg;
             }
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic