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