END block ignored while run_cmd() is executing

Fulko Hew fulko.hew at gmail.com
Thu Apr 12 16:52:38 CEST 2012

On Thu, Apr 12, 2012 at 2:07 AM, Marc Lehmann <schmorp at schmorp.de> wrote:
> On Tue, Apr 10, 2012 at 08:40:44AM -0400, Fulko Hew <fulko.hew at gmail.com> wrote:
>> > My guess is that your problem is elsewhere (tty settings, shell, terminal
>> > emulator...), or maybe your test program works on your system, too?
>> For another independent test, I just booted Fedora 16 (KDE) Live,
>> and tried to run that test example (without any changes/downloads etc.
>> to the booted system, because Coro, AnyEvent, and AnyEvent:Uti
>> are already part of that distribution.)
>> It failed, just as originally reported, witness below...
> If you can create an strace -f of a failing run, I will look at that, and
> maybe see what's going wrong.

An strace log file is attached.
(No its not. was sent in the private email since the mailing list was
holding my email due to its excessive size.)

> Otherwise, I need a program that I can use to reproduce the problem, or
> somebody ahs to analyze the problem on a system where it doesn't work.

Booting and running off of that 'Fedora 16 Live' DVD
was a simple test environment.

> Hmm, looking at your example again, you are blocking in an event loop
> callback, which means anything can happen (including memory corruption,
> depending on the loop in use).
> Do you still get the behaviour if you don't use a blocking wait in
> obtainer?

I prefer to have the block in the obtainer so that nothing proceeds till
the run_cmd() has completed and all the data is available (lest the
daisy chaining of callbacks become too overwhelming).

> Or put it into a Coro async?

I had tried async{} in the past to get around other problems
(and it didn't) and so when I got to this issue... I never thought
about trying async again.  So... I changed it to the following:

sub obtainer {
   async {
       print "END not accessible while run_cmd() is executing... wait
5 seconds till its done\n";
       my $bufRef = get_cmd_data("sleep 5");
       print "run_cmd() done, END is now reachable on CTL C\n";

And the END block(s) are now being reached again.  :-)
And I can use this in my real app too.

[It _is_ interesting though, that it doesn't fail in your environments! ]

In retrospect, I see and understand the 'block in an event loop'
issue. Unfortunately its a very common paradigm to (accidentally)
fall into.  Ie. Every once in a while 'do something (non-trivial that
involves events)'.
In this case I was able to use async{} to get around the issue.
(Others in the future may not be that easy.)

...After decades in real-time OS environments I blindly
proceeded (thinking incorrectly despite constantly reading 'callback'
in your documentation) as if 'all timed things are independent tasks'
rather than simple callbacks. :-(

> Also, at least debians version of Coro is from 2009 (ubuntu probably too),
> which is just, uhm, 16 releases behind. if you call exit in another thread
> then END blocks might not run (as documented in those versions).

Your warning is heeded, but in my case (not the 'F16 Live' test case)
my system didn't even have Coro available, so I had installed the latest
and greatest from CPAN.

Thanks for your support.

More information about the anyevent mailing list