<div dir="ltr"><div class="gmail_default" style="font-family:courier new,monospace"><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 20, 2013 at 4:21 AM, Marc Lehmann <span dir="ltr"><<a href="mailto:schmorp@schmorp.de" target="_blank">schmorp@schmorp.de</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">On Wed, Nov 20, 2013 at 05:56:42PM +1000, Andrew Whatson <<a href="mailto:whatson@gmail.com">whatson@gmail.com</a>> wrote:<br>


> After further investigation, it seems the problem is caused by the<br>
> fact that constructing AnyEvent::Run with an "on_read" parameter<br>
> causes a read watcher for the socketpair to be created *before*<br>
> forking.  This watcher then exists in both the parent and child,<br>
> causing some weird behaviour.<br>
<br>
</div>Well spotted.<br></blockquote><div><br><div class="gmail_default"><span style="font-family:courier new,monospace">Thank you,</span></div><span style="font-family:courier new,monospace">I <div class="gmail_default" style="font-family:courier new,monospace;display:inline">

failled/</div>forgot to realize it was doing that; it was never<br>my intent<div class="gmail_default" style="font-family:courier new,monospace;display:inline"> </div>to attempt to inherit event handling in the child.</span><br>

 <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
@fulko:<br>
<br>
Forking in a program using AnyEvent and then trying to use event handling<br>
in both parent and child is doomed from the beginning, because you never<br>
know who registered which watchers, and they are either active in both<br>
parent and child, or (with many of the more advanced event loops that are<br>
not EV) will not even work. (the FORK section in the AnyEvent manpage goes<br>
into a little bit more detail, as Andrew also pointed out).<br>
<br>
The only safe way to use fork from perl is to use something like<br>
Proc::FastSpawn (when threads are involved you need to fork+exec from C<br>
code) or the good old fork+exec (in all other cases). Or in other words,<br>
fork is to start new programs via exec, not for parallel processing.<br>
<br>
Trying to do parallel processing with fork is not going to work except in<br>
the most simplest cases in completely controlled conditions (event loop is<br>
known, all of the code is known).<br></blockquote><div><br><div class="gmail_default" style="font-family:courier new,monospace;display:inline">Because Perl threading would force my variable-sharing issues to be extremely<br>

complicated, I wanted to move instead to: a simple, low-count, multi-process<br>approach with a simple (JSON) message passing between them.<br></div> </div><div><div class="gmail_default" style="font-family:courier new,monospace;display:inline">

... snip ...<br></div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div class="im">> The work-around is to set on_read afterwards:<br>
><br>
>   my $child = AnyEvent::Run->new(cmd => sub { ... });<br>
>   $child->on_read(sub { ... });<br>
<br>
</div>While this can work in this case, it relies on undocumented behaviour<br>
inside Anyevent::Run, and in general has a very fragile dependency on code<br>
that is generally outside of ones control (for example, AnyEvent, during<br>
intiialisation, might create any number of watchers that will malfunction.<br>
Even if AnyEvent doesn't do it, the event loop itself might. Even if the<br>
event loop might not do it, other modules might. And so on.).<br></blockquote><div><br>.<div class="gmail_default" style="font-family:courier new,monospace;display:inline">.. snip ...</div><div class="gmail_default" style="font-family:courier new,monospace;display:inline">

<br></div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">
> It seems to me that this behaviour could be considered a bug in<br>
> AnyEvent::Run.  The patch to fix it there is straightforward, we just<br>
> move AnyEvent::Handle construction into the parent section after the<br>
> call to fork.<br>
<br>
</div>No, it's a design bug in the original program - AnyEvent::Run cannot<br>
ensure that _all_ existing watchers play nicely after fork, and generally<br>
shouldn't need to.<br>
<br>
This is really the same problem as calling exit in a forked subprocess and<br>
wondering why things break, or not setting cloexec on file descriptors<br>
(that you might not even know of) and wondering why things break, or<br>
forking from a threaded program and wondering why things break, and so on.<br>
<br>
fork should be followed by exec or _exit. Trying to do event processing is<br>
simply doomed, and AnyEvent::Run can not ensure anything.<span class=""><font color="#888888"><br></font></span></blockquote><div><br> <div class="gmail_default" style="font-family:courier new,monospace;display:inline">I appreciate the benefits of fork-exec but, to make my application safe,<br>

isn't there just a simple way of 'undef'ing (in the child),<br>anything that AnyEvent or its event loops _might_ have created,<br>(if its done early enough)?<br><br></div><div class="gmail_default" style="font-family:courier new,monospace;display:inline">

Since I haven't found a way to 'easily' share complex data structures<br>between my few, non-AnyEvent compatible 'threads' (that run forever),<br>I find my alternative is to create separate processes for each with<br>

simple message passing between them.  And for code management purposes,<br></div><div class="gmail_default" style="font-family:courier new,monospace;display:inline">I'd like to keep it all within a single file.<br><br>

I don't really want to incur the complexity of getting my appropriate<br>information passed through to the exec'ed application; or to recreate<br>the portable_socketpair communications between my parent and children<br>

(that seems so easy because it comes with AnyEvent::Run)<br>[primarily because I don't understand the details of doing it myself].<br>:-(<br><br></div><div class="gmail_default" style="font-family:courier new,monospace;display:inline">

Fulko<br><br></div></div></div></div></div>