AnyEvent and Strawberry perl issue
Marc Lehmann
schmorp at schmorp.de
Sun Mar 15 00:37:16 CET 2015
On Sat, Mar 14, 2015 at 02:49:34PM +0000, Steve Hay <steve.m.hay at googlemail.com> wrote:
Do you even realise how full of bullshit your reply is? You managed to
completely ignore the biggest issue (that WSAEINPROGRESS has completely
different semantics to EINPROGRESS, despite this being spelled out
_explicitly_ to you), you throw up some bullshit smokescreen arguments
about changing errno.h, or about the precise patch applied by mingw.
And after all that, you have the *gall* to claim you are interested in
examples that break when you completely ignored all the examples given to
you. Every single one.
Touché! I hope you can sleep at night - I couldn't.
> > However, since the perl5porters officially give a fuck about backwards
> > compatibility with existing code, chances of this getting fixed are small,
> > so I will have to slow down AnyEvent by checking for EWOULDBLOCK for just
> > this platform - that's what you get for letting perl6 people take over
> > perl5 to destroy that, too.
>
> As I noted previously in
> http://www.nntp.perl.org/group/perl.perl5.porters/2015/03/msg226589.html
> this level of backwards-compatibility breakage was an unavoidable
I hear this kind of argument all the time, but nothing in that message
epxlains why breakage was unavoidable - you just claim there is an
explanation for it, somewhere, but of course, there isn't.
It would have been trivial to patch perl to not break existing unix
code using EAGAIN (the correct code) and not mapping WSAEINPROGRESS
to EINPROGRESS (because an unknown error code is better then
EINPROGRESS, as POSIX has no equoivalent to WSAEINPROGRESS, it is 100%
windows-specific).
Which effectively rules out any rationale (a rationale might exist, but it
would be wrong).
*Any* claims that this breakage was *unavoidable* are simply bullshit.
> consequence of fixing something else. The breakage only occurs if
> you're testing for hard-coded numbers like 10035 rather than named
I also hear bullshit like "breakage only occurs" on *replies* to messages
which prove this wrong.
I am testing for both windows socket error codes as well as posix error
codes. not hardcoded numbers. And the code breaks because WSAEINPROGRESS
matches Errno::EINPROGRESS.
This is not only proving your statement wrong, it also can't be fixed
except by writing more win32-specific workaround code. Worse, perl version
and win32-specific code.
But are you honest enough to admit that? I have my doubts, given your
demonstrated ability to ignore actual argument in favour of some strawmen
that burns like tinder.
> says "Why should this be done? POSIX [1] does not require this.
> Portable applications have to check against both EAGAIN and
> EWOULDBLOCK." and cited the page
Again, I hear bullshit arguments like this all the time, arguments
that only work because you ignored the actual argument that I wrote in
my mail: It doesn't matter what POSIX says, virtually every existing
platform uses only EAGAIN, and being incompatible *on purpose* has no
value whatsoever. You can count the breakage that occurs due to AnyEvent
not testing for EWOULDBLOCK easily on cpan-testers - zero. none, except,
possibly, on the botched win32 perl. And on the latter platform, AnyEvent
is broken much more subtly as well now.
Or in other words, native win32 perl tried to be more like unix, but
made itself incompatible to every existing platform, including previous
versions of itself. Well done.
Can you explain why it was neccessary to implement some unix emulation
incompatibly with every unix in existance? Surely you have some rationale
for that, hmm? (Likely in the style of "see unrelated mail here, by force
of claim I decree it is related and contains magic hidden rationale",
though, why do I even bother to ask).
Also, care to explain why and where POSIX somehow mandates that
WSAEWOULDBLOCK should be mapped to EWOULDBLOCK? No, of course, that's not
in POSIX, that's an arbitrary decision in perl, not supported by anything
in POSIX, msdn, or existing unix systems.
And lastly, POSIX is basically always a red herring: POSIX is a baseline
standard that Perl happily ignores if it needs to. Moreso, a correct fix
would still be POSIX-compliant. But it would also be real-world compatible
with existing systems implementing POSIX...
> Furthermore, subsequent replies to the mingw email that you cited make
> it clear that the above patch was not applied anyway. The final patch
I never claimed that the patch was applied. I claimed that mingw maps
WSAEWOULDBLOCK to EAGAIN, which you seem to have verified.
That was a nice attempt to put up a smokescreen, but you can do even
better:
> but I do not think it is perl's place to go making changes like that
> to the compiler suite's errno.h.
Nobody asked for the compilers errno.h to be patched. This is about perl
on win32, not C's errno.h: Quite obviously, you can map WSAEWOULDBLOCK to
EWOULDBLOCK without changing errno.h, and likewise you can map any other
windows-specific error code to whatever posix error code you wish.
These last two arguments are simply idiotic attempts to derail this
discussion with irrelevance, as they have nothing whatsoever to do with
the problem.
But I am used to this too - ignore the criticism, put up a wall of
unrelated bullshit.
But it gets better:
> Perl should simply use whatever
Maybe, but Perl doesn't use whatever errno.h was supplied, it maps
unrelated socket error codes to those errno codes. That is the problem.
These arguments are completely irrelevant, only designed to confuse the
issue with bullshit.
> (b0ba219002 to 7bf1409065) resolved. The problem was that if perl
> changes some Exxx values in errno.h then those values no longer match
> the values used by other libraries built with the standard errno.h,
Oh god, more bullshit - if perl maps socket error codes to other codes
they will *never* match other libraries that don't do that, no matter
what.
You obviously didn't care about incompatibilities when the mapping was
implemented, so why bring this up now? Perl is already incompatible to
other libraries.
> So I still think the correct answer here is for AnyEvent to test for
> both EAGAIN and EWOULDBLOCK, as any portable application should do.
No, the correct answer is: Oh damn, we fucked it up, we made perl
incompatible to all previous perl versions AND every unix platform out
there.
But yes, breaking stuff for no value whatsoever, and then blaming the
victim, that's good form these days.
> > (connect $state{fh}, $sockaddr)
> > || ($! == Errno::EINPROGRESS # POSIX
> > || $! == Errno::EWOULDBLOCK
> > # WSAEINPROGRESS intentionally not checked - it means something else entirely
> > || $! == AnyEvent::Util::WSAEINVAL # not convinced, but doesn't hurt
> > || $! == AnyEvent::Util::WSAEWOULDBLOCK)
> >
> > cygwin gets this right as well.
> >
> > So this change probably breaks connections because the WSA error code is
> > mapped on the wrong POSIX code. I don't think this can be fixed nicely
> > either, it needs to be fixed in perl, where the incorrect mapping is.
>
> I do not see how this will break.
Of course not, that would have required some research and diligence. Or
maybe skimming my original mail, which explains it. Too difficult for you?
I keep repeating myself, but here, again, in slow motion, just for you
who has so much trouble reading (or, as I have to suspect, ignores valid
arguments on purpose):
1. WSAEINPROGRESS has nothing whatsoever to do with EINPROGRESS. perl
merged both to mean the same.
2. if connect returns with an error of WSAEINPROGRESS, it means the connect
has failed.
3. if connect returns with an error of EINPROGRESS on a unix (or POSIX
platform), it means the connect is under way, and the user will
be notified.
4. if connect returns with an error of EINPROGRESS on some perl win32
configs, it means the connect has failed, and no notification will
ever arrive.
Code that relies on the correct error codes will timeout (at best) or
hang due to this change, instead of returning an error (because it will
misinterpret WSAEINPROGRESS as EINPROGRESS, which has completely different
meaning).
AFAICS, this is true for every single case of WSAEINPROGRESS - it always
means that the operation has not been done, while the POSIX EINPROGRESS
code means the opposite.
> So in all cases the test against EWOULDBLOCK works and there is no
> breakage.
Obviously wrong, as was clear from the beginning. Do you see it now and
are you honest enough to admit to have fucked up?
> I am not yet convinced of any problem with our mapping of WSAExxx
> codes to Exxx codes when these are assigned to $!,
That means either you completely ignored all the epxlanations on why it is
wrong (you certainly ignored _all_ my arguments), or you just can't
understand, in which acse you should leave this to people who know what they
are doing.
In general, the WSA codes do not have the same semantics as the POSIX/Unix
error codes. For every single mapping you would need to do some proper
research, because a) existing code relies on this and b) you should try
to understand what you are doing before attempting it.
Extremely few WSA codes map to their same-named counterparts - those
could be translated to make portable progrmaming easier. Many map to some
similar posix code (an argument could be made for translating those). Many
map to different POSIX codes for different calls, and translating them in
operation-independent ways will break things badly. And many have no POSIX
counterpart at all.
This is blatantly obvious for WSAEINPROGRESS (it has nothing to do with
EINPROGRESS), but also true for WSAEWOULDBLOCK - if you attempt to map
WSAEWOULDBLOCK to a POSIX error code, you should go and see which one
that is. And if everybody else returns EAGAIN, you shouldn't return
EWOULDBLOCK. And it doesn't stop there: WSAEMFILE isn't the same as
EMFILE, WSAEINTR doesn't have the same semantics as EINTR (completely
unrelated), WSAEFAULT doesn't have the meaning of EFAULT (namely usually
EINVAL). WSAEACCESS doesn't map to EACCESS (but typically to EADDRINUSE or
a similar error).
On the positive side, WSAEALREADY probably maps well to EALREADY, and
likewise WSAEBADF.
So out of 8 WSA codes I looked at, perl maps 6 to the wrong POSIX errno
code. Which menas portable (in the real sense) applications will all have
to implement some perl version-specific check to ignore these codes or map
these codes to correct behaviour, something which was easy before when you
could test for the WSA error code.
I don't even know how to begin detecting the broken perl versions and
somehow ignoring these spurious ENPROGRESS on them, for example.
Arguing that it was somehow *neccessary* to be incompatible on purpose is
at best disingenious - nobody forced you to be different.
No, all your explanations are after-the-fact bullshit - somebody
simply thought that replacing basically all the WSAExxx codes by
corresponding Exxx codes because their names matched so nicely, completely
ignoring their different semantics and completely ignoring the fact
that applications out there might need to know whether they deal with a
specific winsocket error that requires a speciifc response.
The patch has been made precisely by somebody who thought the symmetry
in naming between those error codes implies a symmetry in semantics,
without doing any experiments, without comparing winsocket and posix
documentation, or in other words, by a person mostly clueless in socket
programming on windows and unix.
While wearing blindfolds.
Exactly the right person for the job of implementing
compatibility-breaking changes.
Not.
> but I would be interested to hear of any other concrete examples of
> problems that you have encountered which do not boil down to having
> tested hard-coded numbers instead of using named constants.
I can't believe you are honest - if you were really intersted in concrete
examples, you wouldn't have ignored basically everything I wrote, which
has nothing whatsoever to do with testing hard-coded numbers.
Specifically, you ignoring the smoking gun, namely mapping completely
unrelated error codes that leads to real-world breakage.
There are some more examples in AnyEvent, even in the intro tutorial:
It also works around a lot of portability quirks (especially on the
windows platform), which makes it even easier to write your programs in a
portable way (did you know that windows uses different error codes for all
socket functions and that Perl does not know about these? That "Unknown
error 10022" (which is C<WSAEINVAL>) can mean that our C<connect> call was
successful? That unsuccessful TCP connects might never be reported back
to your program? That C<WSAEINPROGRESS> means your C<connect> call was
ignored instead of being in progress? AnyEvent::Socket works around all of
these Windows/Perl bugs for you).
I guess it should be called: "Did you know that perl maintainers think
your program should be broken and working around windows quirkks should be
made as hard as possible?").
And of course in the code, for example from AnyEvent::Loop:
} elsif (AnyEvent::WIN32 && $fds && $! == AnyEvent::Util::WSAEINVAL) {
# buggy microshit windoze asks us to route around it
Yup, when select returns WSAEINVAL, it has nothing to do with POSIX
EINVAL. Different error code, different behaviour, different, now broken,
workaround. (and in case you don't know, EINVAL in POSIX indicates that
the timeout value is invalid, while WSAEINVAL indicates your fd sets were
empty and you needs to wait manually - merging them can make programs do
busy-waiting loops instead of sleeping).
Of course, you could have fixed your select emulation to actually work
like POSIX (or any existing unix platforms), but that would have been too
much to ask for, no, it is much cooler to keep it broken whole making it
harder to work around it from Perl code.
> If there are indeed other problems in the current design then we
> would, of course, be keen to fix them, although doing so in a manner
> that doesn't reintroduce other bugs that have already been fixed may
> not be easy.
Yeah, I know this pattern - you break it, and when somebody complains,
you argue that the breakage is the new standard and was unavoidable,
without substantiation wathsoever and despite arguments to the opposite,
which get ignored. AnyEvent has to deal with your inability to maintain
perl properly already, and will likely have to do so in the future as
well. Nothing new here.
The honest solution would be to fix bugs and breakage that was introduced,
but that is completely out of the question for perl5porters (has "warn"
been fixed? no. has extutils' typemap for char * been fixed for being
incompatible with older perl versions? no. has the security-theatre hash
breaking patch been reverted? no. and so on and so on...).
If you want to be able to tell me you care for breakage, or that breakage
is unavoidable, you will first have to make me stop laughing. Or crying.
I think this mail makes it clear why I am disappointed with your
substandard attempt of a reply. I am sure, as always, the next step will
be to ignore all the arguments from this mail as well, and attacking me
personally, because it is so much easier to attack the messenger.
Oh, the pain.
--
The choice of a Deliantra, the free code+content MORPG
-----==- _GNU_ http://www.deliantra.net
----==-- _ generation
---==---(_)__ __ ____ __ Marc Lehmann
--==---/ / _ \/ // /\ \/ / schmorp at schmorp.de
-=====/_/_//_/\_,_/ /_/\_\
More information about the anyevent
mailing list