Re: POE::Wheel::Run::Win32 and Win32::Daemon

Andrew Feren <[email protected]>
Newsgroups gmane.comp.lang.perl.poe
Message-ID <[email protected]>

Andreas Altergott wrote:
> Hi,
>
> Andrew Feren wrote:
>   
>> I removed the calls to exit() and the service started working as
>> expected.  Calling exit() from the child resulting from perl's pseudo
>> fork is supposed to work (and often does).  Unfortunately it has been my
>> experience that sometimes the results are a catastrophic  failure.
>>     
>
> That's a surprise.  So the exit subroutine must call something
> different, than simply letting the program run out.  That would be a
> nice question to the ActiveState developers.
>   
This is an area that has always bothered me.

The "perlfork" docs state :

    /exit()/ always exits just the executing pseudo-process, after
    automatically /wait()/-ing for any outstanding child
    pseudo-processes. Note that this means that the process as a whole
    will not exit unless all running pseudo-processes have exited.

This makes sense since the goal, as I understand it, is to as much as 
possible have fork() code just work on Windows.  For many examples it does.

Perl threads started life as a way to implement "perlfork".  OK, so far 
so good.  However, if we read the "threads" documentation we find :

    *exit(status)*

    Calling exit EXPR <http://perldoc.perl.org/functions/exit.html>
    inside a thread causes the whole application to terminate. Because
    of this, the use of |exit()| inside threaded code, or in modules
    that might be used in threaded applications, is strongly discouraged.

    If |exit()| really is needed, then consider using the following:

       1. threads->exit() if threads->can('exit'); # Thread friendly
       2. exit(status);

Clearly pseudo-processes (aka threads ;) are intended to do the right 
thing relative to exit (and with good reason).  However, the foundation 
they are built on is very exit() averse.
> There is the possibility to use fork() as long as you do not use exit()
> then.  Probably that's why threads have been working.  I did not use
> exit() there.
>   
You *really* don't want to call exit() if you are using threads directly.
> I'm just curious.  Is there another way to stop a POE application
> immediately?
>   
The answer depends a little on your intent.  If you really want to 
terminate an application inclusive all threads exit() works great (as 
long as you don't need to do any cleanup ;).  If you just want to 
terminate a single thread try threads->exit() (if it is available). 

After tripping over problems with exit() a couple times I just take care 
to have a code path that will quietly run out of things to do without 
calling exit() explicitly. 
> There's the possibility of using stop().  If I run this inside the
> forked child, this should not affect the parent.  But still some code in
> the _stop state will get executed.
>
>   
>> How did you use exec()?  calling exec() after the fork() failed for me
>> in the same way as calling exit.
>>     
>
> I did not try to run exec() from a fork.  That's sad to hear, else one
> could use Wheel::Run by setting the program to an array.  This would run
> exec() on line 443, instead of the final exit() on line 440 in Wheel::Run.
yep.  That was what I thought too, but no luck.

IMO death by exit() in a pseudo-process is a bug, but it isn't clear if 
the bug is in the "perlfork" implementation my code or some 
combination.  I did notice that Win32::Daemon starts several threads.  
 From the outside looking in I can't tell if they are pseudo-processes 
or threads, but I'd guess they are threads.  Which brings me to this 
quote from the perl thread tutorial.

    "Thinking of mixing |fork()| and threads? Please lie down and wait
    until the feeling passes."

I think, from the rest of the context, that this quote is referring to a 
real UNIX fork() and not "perlfork", but then again...

I wonder if calling exit from a pseudo-process would kill off threads 
that happen to be running and aren't also pseudo processes.

-Andrew
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.