tag 543731 patch
thanks

On Thu, Aug 27, 2009 at 05:39:34PM +1000, Paul Fenwick wrote:
> Niko Tyni wrote:
> 
> > The problem is that errno.h has separate values for EAGAIN (11) and
> > EWOULDBLOCK (246) on hppa and the kernel is returning EAGAIN (contrary
> > to the flock(2) manual page.) Some background for this can be found in
> 
> > I suppose that regardless of whether this is ever fixed on the kernel
> > and/or documentation side, t/flock.t and lib/Fatal.pm need to check for
> > both EWOULDBLOCK and EAGAIN for compatibility.
> 
> Drat.  EAGAIN actually makes me feel funny, because I've always interpreted
> it to mean "I got distracted there, please try that again".  However in this
> case, we *don't* want to try again, because we'll spin the CPU trying to get
> a lock in non-blocking mode.
> 
> So ideally I'd only want to check for EAGAIN on hppa architectures.  That
> should be easy enough for me to detect at compile-time, however I don't have
> a PA-RISC box handy to see how they identify themselves.

The attached patch fixes the autodie 2.06_01 test suite for me on
hppa without breaking it on amd64 :) Hope you can use it at least as a
starting point.

(dropped p5p for now)

Cheers,
-- 
Niko Tyni   nt...@debian.org
>From 00960c2d7b761522c06e3b4e1418019ebad2681b Mon Sep 17 00:00:00 2001
From: Niko Tyni <nt...@debian.org>
Date: Sun, 30 Aug 2009 13:58:35 +0300
Subject: [PATCH] Allow for flock returning EAGAIN instead of EWOULDBLOCK on linux/parisc

Contrary to the documentation, flock(2) returns EAGAIN instead of
EWOULDBLOCK on the Linux parisc port (aka. hppa).

http://bugs.debian.org/543731
---
 lib/Fatal.pm |   14 +++++++++++++-
 t/flock.t    |   12 ++++++++++--
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/lib/Fatal.pm b/lib/Fatal.pm
index 18e71ed..c17a257 100755
--- a/lib/Fatal.pm
+++ b/lib/Fatal.pm
@@ -5,6 +5,7 @@ use Carp;
 use strict;
 use warnings;
 use Tie::RefHash;   # To cache subroutine refs
+use Config;
 
 use constant PERL510     => ( $] >= 5.010 );
 
@@ -52,6 +53,10 @@ our %_EWOULDBLOCK = (
     MSWin32 => 33,
 );
 
+# the linux parisc port has separate EAGAIN and EWOULDBLOCK,
+# and the kernel returns EAGAIN
+my $try_EAGAIN = ($^O eq 'linux' and $Config{archname} =~ /hppa|parisc/) ? 1 : 0;
+
 # We have some tags that can be passed in for use with import.
 # These are all assumed to be CORE::
 
@@ -720,6 +725,11 @@ sub _one_invocation {
         my $EWOULDBLOCK = eval { POSIX::EWOULDBLOCK(); }
                           || $_EWOULDBLOCK{$^O}
                           || _autocroak("Internal error - can't overload flock - EWOULDBLOCK not defined on this system.");
+        my $EAGAIN = $EWOULDBLOCK;
+        if ($try_EAGAIN) {
+            $EAGAIN = eval { POSIX::EAGAIN(); }
+                          || _autocroak("Internal error - can't overload flock - EAGAIN not defined on this system.");
+        }
 
         require Fcntl;      # For Fcntl::LOCK_NB
 
@@ -735,7 +745,9 @@ sub _one_invocation {
             # If we failed, but we're using LOCK_NB and
             # returned EWOULDBLOCK, it's not a real error.
 
-            if (\$_[1] & Fcntl::LOCK_NB() and \$! == $EWOULDBLOCK ) {
+            if (\$_[1] & Fcntl::LOCK_NB() and
+                (\$! == $EWOULDBLOCK or
+                ($try_EAGAIN and \$! == $EAGAIN ))) {
                 return \$retval;
             }
 
diff --git a/t/flock.t b/t/flock.t
index a7550ba..6421a56 100755
--- a/t/flock.t
+++ b/t/flock.t
@@ -2,7 +2,8 @@
 use strict;
 use Test::More;
 use Fcntl qw(:flock);
-use POSIX qw(EWOULDBLOCK);
+use POSIX qw(EWOULDBLOCK EAGAIN);
+use Config;
 
 require Fatal;
 
@@ -10,6 +11,9 @@ my $EWOULDBLOCK = eval { EWOULDBLOCK() }
                   || $Fatal::_EWOULDBLOCK{$^O}
                   || plan skip_all => "EWOULDBLOCK not defined on this system";
 
+my $try_EAGAIN = ($^O eq 'linux' and $Config{archname} =~ /hppa|parisc/) ? 1 : 0;
+my $EAGAIN = eval { EAGAIN() };
+
 my ($self_fh, $self_fh2);
 
 eval {
@@ -55,7 +59,11 @@ eval {
     $return = flock($self_fh2, LOCK_EX | LOCK_NB);
 };
 
-is($!+0, $EWOULDBLOCK, "Double-flocking should be EWOULDBLOCK");
+if (!$try_EAGAIN) {
+    is($!+0, $EWOULDBLOCK, "Double-flocking should be EWOULDBLOCK");
+} else {
+    ok($!+0 == $EWOULDBLOCK || $!+0 == $EAGAIN, "Double-flocking should be EWOULDBLOCK or EAGAIN");
+}
 ok(!$return, "flocking a file twice should fail");
 is($@, "", "Non-blocking flock should not fail on EWOULDBLOCK");
 
-- 
1.5.6.5

Reply via email to