[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

at_exit() Inherited Across fork

James Gray

12/7/2007 8:34:00 PM

I'm not saying this is wrong, just clarifying what I am seeing. Is it
intended that at_exit() handlers are inherited by a fork()ed process?
For example:

at_exit { puts "Doing something important for #{Process.pid}." }
fork

James Edward Gray II


7 Answers

Adam Bozanich

12/7/2007 9:04:00 PM

0

Note: parts of this message were removed by the gateway to make it a legal Usenet post.

On Dec 7, 2007 12:33 PM, James Gray <james@grayproductions.net> wrote:

> I'm not saying this is wrong, just clarifying what I am seeing. Is it
> intended that at_exit() handlers are inherited by a fork()ed process?
> For example:
>
> at_exit { puts "Doing something important for #{Process.pid}." }
> fork


Makes sense to me.

#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>

static void handler() {
printf("handler for pid %d\n",getpid());
}

int main() {
atexit(handler);
if(fork()) wait(0);
return 0;
}

-Adam

ara.t.howard

12/8/2007 1:27:00 AM

0


On Dec 7, 2007, at 1:33 PM, James Gray wrote:

> I'm not saying this is wrong, just clarifying what I am seeing. Is
> it intended that at_exit() handlers are inherited by a fork()ed
> process? For example:
>
> at_exit { puts "Doing something important for #{Process.pid}." }
> fork
>
> James Edward Gray II
>

it's expected, and easy to get around if you want:

fork do
at_exit{ exit! }
end

you just have to do it right up front in order to dis-own the
handlers from the parent - i do this is slave.rb or open4.rb - can't
recall which offhand.

cheers.

a @ http://codeforp...
--
it is not enough to be compassionate. you must act.
h.h. the 14th dalai lama




James Gray

12/8/2007 2:49:00 AM

0

On Dec 7, 2007, at 7:26 PM, ara.t.howard wrote:

>
> On Dec 7, 2007, at 1:33 PM, James Gray wrote:
>
>> I'm not saying this is wrong, just clarifying what I am seeing. Is
>> it intended that at_exit() handlers are inherited by a fork()ed
>> process? For example:
>>
>> at_exit { puts "Doing something important for #{Process.pid}." }
>> fork
>>
>> James Edward Gray II
>>
>
> it's expected, and easy to get around if you want:
>
> fork do
> at_exit{ exit! }
> end
>
> you just have to do it right up front in order to dis-own the
> handlers from the parent - i do this is slave.rb or open4.rb - can't
> recall which offhand.

This is pretty much how we solved it. We used exit!() in the fork()ed
process.

I guess it just kind of feels like the scripting language should be
doing something more clever for us here so we don't have to do this
kind of stuff though.

James Edward Gray II

ara.t.howard

12/8/2007 3:45:00 AM

0


On Dec 7, 2007, at 7:48 PM, James Gray wrote:

> This is pretty much how we solved it. We used exit!() in the fork()
> ed process.

you don't want to do that really - any at_exit handlers in the child
will not be called. for instance, if you are using tmpfiles they
will not be cleaned up.

>
> I guess it just kind of feels like the scripting language should be
> doing something more clever for us here so we don't have to do this
> kind of stuff though.


i personally prefer ruby to violate c semantics as little as possible
but i can see it being surprising too. so long as we can easily
obtain both behaviors it hardly matters...

btw. another approach is to for the children before setting up the
exit handlers - you just have to arrange for them to hang around
waiting to do something, reading the cmd to execute from a pipe to
the parent for example.

one other note - when i write rq i had bizarre issues caused by
forking from inside an sqlite transaction (virtually no db supports
this actually) - what i ended up doing is to create a drb process
that is owned by the parent. the parent then asks this drb process
to fork on it's behalf to do something. the interface supports
Process.wait, etc, but the forking is actually occuring in child
that's creating grandchildren. by using this approach the drb
process can be setup early before the initial process has had a
chance to setup at_exit handlers and also before it's gotten big.

cheers.

a @ http://codeforp...
--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama



Joel VanderWerf

12/8/2007 3:47:00 AM

0

James Gray wrote:
> I guess it just kind of feels like the scripting language should be
> doing something more clever for us here so we don't have to do this kind
> of stuff though.

I'd rather that ruby mirror the C API, and make it easy to add your own
behavior on top of that.

What about something like this?

module Kernel
def at_exit_in_this_process(&handler)
unless $at_exit_in_this_process
$at_exit_in_this_process = Hash.new{|h,k| h[k]=[]}
at_exit do
$at_exit_in_this_process[Process.pid].reverse_each do |hdlr|
hdlr.call
end
end
end
$at_exit_in_this_process[Process.pid] << handler
end
end

at_exit_in_this_process {p 1}
fork do
at_exit_in_this_process {p 2}
end
Process.wait

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Gary Wright

12/8/2007 5:07:00 AM

0


On Dec 7, 2007, at 10:47 PM, Joel VanderWerf wrote:

> James Gray wrote:
>> I guess it just kind of feels like the scripting language should
>> be doing something more clever for us here so we don't have to do
>> this kind of stuff though.
>
> I'd rather that ruby mirror the C API, and make it easy to add your
> own behavior on top of that.

My quick read of <http://www.opengroup.org/onlinepubs/...
functions/atexit.html> suggests
that atexit handlers are only called when exit() is called or main()
returns. So atexit()
handlers are not called before a fork in the C/POSIX world.

If Ruby's at_exit() behavior differs from this, I'm not seeing it.

Gary Wright

Joel VanderWerf

12/8/2007 6:43:00 AM

0

Gary Wright wrote:
>
> On Dec 7, 2007, at 10:47 PM, Joel VanderWerf wrote:
>
>> James Gray wrote:
>>> I guess it just kind of feels like the scripting language should be
>>> doing something more clever for us here so we don't have to do this
>>> kind of stuff though.
>>
>> I'd rather that ruby mirror the C API, and make it easy to add your
>> own behavior on top of that.
>
> My quick read of
> <http://www.opengroup.org/onlinepubs/009695399/functions/atexi...
> suggests
> that atexit handlers are only called when exit() is called or main()
> returns. So atexit()
> handlers are not called before a fork in the C/POSIX world.
>
> If Ruby's at_exit() behavior differs from this, I'm not seeing it.
>
> Gary Wright

What I meant to say was, I'd rather that ruby *continue* to mirror the C
API... I'm a ruby conservative :)

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407