open() with pipe breaks AnyEvent STDIN poll
Nick Andrew
nick at nick-andrew.net
Wed Nov 26 14:15:20 CET 2014
On Wed, Nov 26, 2014 at 01:26:47PM +0100, Marc Lehmann wrote:
> On Wed, Nov 26, 2014 at 06:10:43PM +1100, Nick Andrew <nick at nick-andrew.net> wrote:
> > I found a problem where a working AnyEvent script broke badly because
> > of some code in a 3rd party module called from the script. I isolated
> > it to the call to open(CMD, "command |").
>
> The callback modifies $_, which is a global variable, without restoring it,
> so code outside the watcher will have its loop variable destroyed.
Ok. I wasn't aware that $_ is a global variable; it didn't even enter my
thinking as you can see; I thought the problem was with file handles and
STDIN; the while (<FH>) loop didn't even occur to me as the source of
the problem.
> This is, strictly speaking, a bug in the 3rd party module - it shouldn't
> trash variables in use by the caller. The workaround is easy though, just add
> a local $_ before you call it.
I added this and the script resumed working as expected:
cb => sub {
local $_;
call_into_third_party_module();
[...]
> > which case it deserves a big fat warning somewhere in the AnyEvent documentation)?
>
> There is one in bold letters in the WATCHERS section (and the perlop
> docs also mention that $_ isn't localised by while and you would need an
> explicit local $_ for that):
I guess the problem here is that I wasn't even aware that $_ was being
changed by something; it took me about 6 hours of debugging to isolate
the problem down to the open() ... while ... cause it's not my 3rd
party code.
> It is probably useful to report the bug to the 3rd party lib, as modifying
> the caller's $_ variable is likely going to break other code as well and
> is usually hard to diagnose (outside of AnyEvent's strict mode :).
I'll report it but unsure of my ability to get the code changed.
Would it be reasonable for AnyEvent to change to not use $_ within
the event loop, to prevent a whole class of problems and protect its
own data structures?
Nick.
--
PGP Key ID = 0x418487E7 http://www.nick-andrew.net/
PGP Key fingerprint = B3ED 6894 8E49 1770 C24A 67E3 6266 6EB9 4184 87E7
More information about the anyevent
mailing list