OSProcess: making sure that a child process always dies

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

OSProcess: making sure that a child process always dies

Joshua Gargus-2
Hi,

Is there a way to use OSProcess on OS X (or unix in general) to cause  
forked child processes to die when the parent Squeak process quits?

Thanks,
Josh

Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

johnmci
when I asked that question last fall, when I was trying to figure out  
how the VM process forked by the browser plugin would terminate
if the browser crashed, someone mentioned.

                if (getppid() == 1)

if getppid returns 1, then the original parent process has gone  
away.   I added this check to the VM when it knows it's running as a
subtask of the browser and as a chore we do every couple of seconds.


On Mar 15, 2007, at 12:15 AM, Joshua Gargus wrote:

> Hi,
>
> Is there a way to use OSProcess on OS X (or unix in general) to  
> cause forked child processes to die when the parent Squeak process  
> quits?
>
> Thanks,
> Josh
>

--
========================================================================
===
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
========================================================================
===



Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

Joshua Gargus-2
Hi John,

Unfortunately, in this case I'm forking Someone Else's Binary, not a  
Squeak image that is itself running OSProcess.  It's GPLed, so I  
could always hack it if necessary, but I'd rather do it from Smalltalk.

Thanks for the idea,
Josh


On Mar 15, 2007, at 12:48 AM, John M McIntosh wrote:

> when I asked that question last fall, when I was trying to figure  
> out how the VM process forked by the browser plugin would terminate
> if the browser crashed, someone mentioned.
>
> if (getppid() == 1)
>
> if getppid returns 1, then the original parent process has gone  
> away.   I added this check to the VM when it knows it's running as a
> subtask of the browser and as a chore we do every couple of seconds.
>
>
> On Mar 15, 2007, at 12:15 AM, Joshua Gargus wrote:
>
>> Hi,
>>
>> Is there a way to use OSProcess on OS X (or unix in general) to  
>> cause forked child processes to die when the parent Squeak process  
>> quits?
>>
>> Thanks,
>> Josh
>>
>
> --
> ======================================================================
> =====
> John M. McIntosh <[hidden email]>
> Corporate Smalltalk Consulting Ltd.  http://
> www.smalltalkconsulting.com
> ======================================================================
> =====
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

David T. Lewis
In reply to this post by Joshua Gargus-2
On Thu, Mar 15, 2007 at 12:15:01AM -0700, Joshua Gargus wrote:
> Hi,
>
> Is there a way to use OSProcess on OS X (or unix in general) to cause  
> forked child processes to die when the parent Squeak process quits?

You can keep track of the process proxy for the forked child
process, and explicitly terminate it when you exit Squeak, possibly
as part of a class #shutDown: method.

For example, you can kill all child processes like this:
  OSProcess thisOSProcess allMyChildren do: [:e | e terminate]

Dave


Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

Joshua Gargus-2
Hi David,

Thanks, that's what I had implemented.  However, the OS X VM has a  
menu item "Quit do not save" which appears not to go through the  
regular Squeak shutdown process.  Also, you never know when you'll  
have to terminate an image with "extreme prejudice" :-)

I suppose that another option would be to stash the pids in a file  
and kill them on startup.

Thanks to you and John for the suggestions.  I'm not a unix expert,  
and I had no idea what support the underlying APIs had for this use  
case.

Cheers,
Josh


On Mar 15, 2007, at 4:58 AM, David T. Lewis wrote:

> On Thu, Mar 15, 2007 at 12:15:01AM -0700, Joshua Gargus wrote:
>> Hi,
>>
>> Is there a way to use OSProcess on OS X (or unix in general) to cause
>> forked child processes to die when the parent Squeak process quits?
>
> You can keep track of the process proxy for the forked child
> process, and explicitly terminate it when you exit Squeak, possibly
> as part of a class #shutDown: method.
>
> For example, you can kill all child processes like this:
>   OSProcess thisOSProcess allMyChildren do: [:e | e terminate]
>
> Dave
>
>


Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

johnmci

On Mar 15, 2007, at 11:12 AM, Joshua Gargus wrote:

> Hi David,
>
> Thanks, that's what I had implemented.  However, the OS X VM has a  
> menu item "Quit do not save" which appears not to go through the  
> regular Squeak shutdown process.

I'll note I just added two changes in that area

a) if you use the mac menus you can replace the "Quit do not save"  
with something else, like 'Undo'
b) There is an info.plist entry that lets you set the option to do  
the Quit do not save if you invoke logout, versus having the squeak  
vm halt the logout process.

--
========================================================================
===
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
========================================================================
===



Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

Joshua Gargus-2
Wow, thanks John!  That will be useful.

Josh

On Mar 15, 2007, at 11:45 AM, John M McIntosh wrote:

>
> On Mar 15, 2007, at 11:12 AM, Joshua Gargus wrote:
>
>> Hi David,
>>
>> Thanks, that's what I had implemented.  However, the OS X VM has a  
>> menu item "Quit do not save" which appears not to go through the  
>> regular Squeak shutdown process.
>
> I'll note I just added two changes in that area
>
> a) if you use the mac menus you can replace the "Quit do not save"  
> with something else, like 'Undo'
> b) There is an info.plist entry that lets you set the option to do  
> the Quit do not save if you invoke logout, versus having the squeak  
> vm halt the logout process.
>
> --
> ======================================================================
> =====
> John M. McIntosh <[hidden email]>
> Corporate Smalltalk Consulting Ltd.  http://
> www.smalltalkconsulting.com
> ======================================================================
> =====
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

David T. Lewis
In reply to this post by Joshua Gargus-2
On Thu, Mar 15, 2007 at 11:12:01AM -0700, Joshua Gargus wrote:
> Hi David,
>
> Thanks, that's what I had implemented.  However, the OS X VM has a  
> menu item "Quit do not save" which appears not to go through the  
> regular Squeak shutdown process.  Also, you never know when you'll  
> have to terminate an image with "extreme prejudice" :-)

Well, if you anticipate terminating Squeak with the "kill" command
(i.e. send a SIGTERM signal to the VM), then you can do this:

  [OSProcess accessor forwardSigTerm wait.
  OSProcess thisOSProcess allMyChildren
        do: [:child | child isRunning ifTrue: [child terminate]].
    SmalltalkImage current snapshot: false andQuit: true] fork

This will allow Squeak to catch the Unix SIGTERM signal, and
terminate your child processes before exiting.

> I suppose that another option would be to stash the pids in a file  
> and kill them on startup.

Ick.

> Thanks to you and John for the suggestions.  I'm not a unix expert,  
> and I had no idea what support the underlying APIs had for this use  
> case.

I was thinking that setpgrp() might do what you want, so I tried
adding this to OSPP, but it does not seem to behave quite as I
expected.  I'll let you know if I figure something out.

Dave


Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

David T. Lewis
In reply to this post by Joshua Gargus-2
Hi Josh,

I did some more work on this problem, and came up with a good
way to address it. You will need to build a new OSProcessPlugin
and load the latest OSProcess, after which you can do:

        OSProcess thisOSProcess killCurrentChildrenAtExit

This makes use of atexit() to arrange for any currently active child
processes to receive a SIGTERM signal when your Squeak VM exits,
regardless of whether the normal image #shutDown processing occurs.
By "currently active" I mean the child processes that have already
been started, and that are running at the time you do the
#killCurrentChildrenAtExit.

I also added primitives to support Unix setsid(), getpgid(), setpgid(),
getpgrp(), setpgrp() session management functions. You can use these
if you want to experiment further (but I think #killCurrentChildrenAtExit
is much easier).

The latest OSProcessPlugin and OSProcess are here:
 http://www.squeaksource.com/OSProcessPlugin/VMConstruction-Plugins-OSProcessPlugin-dtl.8.mcz 
 http://www.squeaksource.com/OSProcess/OSProcess-dtl.33.mcz

If you try this out, please let me know if it works for you.

Dave

On Thu, Mar 15, 2007 at 11:12:01AM -0700, Joshua Gargus wrote:

> Hi David,
>
> Thanks, that's what I had implemented.  However, the OS X VM has a  
> menu item "Quit do not save" which appears not to go through the  
> regular Squeak shutdown process.  Also, you never know when you'll  
> have to terminate an image with "extreme prejudice" :-)
>
> I suppose that another option would be to stash the pids in a file  
> and kill them on startup.
>
> Thanks to you and John for the suggestions.  I'm not a unix expert,  
> and I had no idea what support the underlying APIs had for this use  
> case.
>
> Cheers,
> Josh
>
>
> On Mar 15, 2007, at 4:58 AM, David T. Lewis wrote:
>
> >On Thu, Mar 15, 2007 at 12:15:01AM -0700, Joshua Gargus wrote:
> >>Hi,
> >>
> >>Is there a way to use OSProcess on OS X (or unix in general) to cause
> >>forked child processes to die when the parent Squeak process quits?
> >
> >You can keep track of the process proxy for the forked child
> >process, and explicitly terminate it when you exit Squeak, possibly
> >as part of a class #shutDown: method.
> >
> >For example, you can kill all child processes like this:
> >  OSProcess thisOSProcess allMyChildren do: [:e | e terminate]
> >
> >Dave
> >
> >
>

Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

Joshua Gargus-2
Thanks David, this is very much appreciated.  I expect to try this  
out in the next week; I'll let you know how it goes.

Cheers,
Josh


On Mar 18, 2007, at 9:48 AM, David T. Lewis wrote:

> Hi Josh,
>
> I did some more work on this problem, and came up with a good
> way to address it. You will need to build a new OSProcessPlugin
> and load the latest OSProcess, after which you can do:
>
> OSProcess thisOSProcess killCurrentChildrenAtExit
>
> This makes use of atexit() to arrange for any currently active child
> processes to receive a SIGTERM signal when your Squeak VM exits,
> regardless of whether the normal image #shutDown processing occurs.
> By "currently active" I mean the child processes that have already
> been started, and that are running at the time you do the
> #killCurrentChildrenAtExit.
>
> I also added primitives to support Unix setsid(), getpgid(), setpgid
> (),
> getpgrp(), setpgrp() session management functions. You can use these
> if you want to experiment further (but I think  
> #killCurrentChildrenAtExit
> is much easier).
>
> The latest OSProcessPlugin and OSProcess are here:
>  http://www.squeaksource.com/OSProcessPlugin/VMConstruction-Plugins- 
> OSProcessPlugin-dtl.8.mcz
>  http://www.squeaksource.com/OSProcess/OSProcess-dtl.33.mcz
>
> If you try this out, please let me know if it works for you.
>
> Dave
>
> On Thu, Mar 15, 2007 at 11:12:01AM -0700, Joshua Gargus wrote:
>> Hi David,
>>
>> Thanks, that's what I had implemented.  However, the OS X VM has a
>> menu item "Quit do not save" which appears not to go through the
>> regular Squeak shutdown process.  Also, you never know when you'll
>> have to terminate an image with "extreme prejudice" :-)
>>
>> I suppose that another option would be to stash the pids in a file
>> and kill them on startup.
>>
>> Thanks to you and John for the suggestions.  I'm not a unix expert,
>> and I had no idea what support the underlying APIs had for this use
>> case.
>>
>> Cheers,
>> Josh
>>
>>
>> On Mar 15, 2007, at 4:58 AM, David T. Lewis wrote:
>>
>>> On Thu, Mar 15, 2007 at 12:15:01AM -0700, Joshua Gargus wrote:
>>>> Hi,
>>>>
>>>> Is there a way to use OSProcess on OS X (or unix in general) to  
>>>> cause
>>>> forked child processes to die when the parent Squeak process quits?
>>>
>>> You can keep track of the process proxy for the forked child
>>> process, and explicitly terminate it when you exit Squeak, possibly
>>> as part of a class #shutDown: method.
>>>
>>> For example, you can kill all child processes like this:
>>>  OSProcess thisOSProcess allMyChildren do: [:e | e terminate]
>>>
>>> Dave
>>>
>>>
>>


Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

Damien Pollet
2007/3/19, Joshua Gargus <[hidden email]>:
> Thanks David, this is very much appreciated.


Hi, and thanks too.

I have a similar problem. The method to intercept sigterm seems to
work only once, so I tried to put a loop in it:

[[
    OSProcess accessor forwardSigUsr1 wait.
    SmalltalkImage current snapshot: true andQuit: false
] repeat ] fork

It works once (I kill -USR1 squeak and get a message in the
transcript), but after that, OSProcess accessor forwardSigUsr1 returns
nil... that's a problem because the goal is to trigger as many
snapshots as needed.

Any ideas ?

--
Damien Pollet
type less, do more [ | ] http://typo.cdlm.fasmz.org

Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

David T. Lewis
On Mon, Mar 19, 2007 at 02:31:06PM +0100, Damien Pollet wrote:

> 2007/3/19, Joshua Gargus <[hidden email]>:
> >Thanks David, this is very much appreciated.
>
>
> Hi, and thanks too.
>
> I have a similar problem. The method to intercept sigterm seems to
> work only once, so I tried to put a loop in it:
>
> [[
>    OSProcess accessor forwardSigUsr1 wait.
>    SmalltalkImage current snapshot: true andQuit: false
> ] repeat ] fork
>
> It works once (I kill -USR1 squeak and get a message in the
> transcript), but after that, OSProcess accessor forwardSigUsr1 returns
> nil... that's a problem because the goal is to trigger as many
> snapshots as needed.
>
> Any ideas ?

Damien,

The expression "OSProcess accessor forwardSigUsr1" answers a semaphore
the should be signaled each time the VM receives a SIGUSR1 from the
operating system. If you create the semaphore once, then wait on
in it a loop, I think it will do what you want.

Dave


Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

Damien Pollet
On 19/03/07, David T. Lewis <[hidden email]> wrote:
> The expression "OSProcess accessor forwardSigUsr1" answers a semaphore
> the should be signaled each time the VM receives a SIGUSR1 from the
> operating system. If you create the semaphore once, then wait on
> in it a loop, I think it will do what you want.

Yes, I put the semaphore in a temporary variable then use it inside
the loop, and it works.

But why does the method answer nil after it was used once?
If the semaphore is a singleton, shouldn't forwardSigUsr1 always
return the same object?

--
Damien Pollet
type less, do more [ | ] http://typo.cdlm.fasmz.org

Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

David T. Lewis
On Mon, Mar 19, 2007 at 08:53:54PM +0100, Damien Pollet wrote:

> On 19/03/07, David T. Lewis <[hidden email]> wrote:
> >The expression "OSProcess accessor forwardSigUsr1" answers a semaphore
> >the should be signaled each time the VM receives a SIGUSR1 from the
> >operating system. If you create the semaphore once, then wait on
> >in it a loop, I think it will do what you want.
>
> Yes, I put the semaphore in a temporary variable then use it inside
> the loop, and it works.
>
> But why does the method answer nil after it was used once?
> If the semaphore is a singleton, shouldn't forwardSigUsr1 always
> return the same object?

I don't have the code in front of me, but I think I set it up so
there would be at most one semaphore associated with a signal type,
and that semaphore is registered in the external objects array.
Thus you can create the semaphore one time, but if you try to
create it again nothing will happen. I guess a warning would have
been better than just answering nil. By the way, you should be
able to unregister the signal forwarder, then the next time you
try register it, it would succeed again (once).

Dave


Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

Joshua Gargus-2
In reply to this post by David T. Lewis
Hi David,

In order to compile the plugin on OS X (using Ian's 3.9-8 from  
squeakvm.org) I had to hack UnixOSProcessPlugin.c so that  
primitiveSetPGrp() calls 'setpgrp(0,0)' instead of 'setpgrp()'.

It appears that OS X and Linux treat these differently.  Under Linux,  
setpgrp() calls setpgid(0,0) , whereas under OS X, setpgrp is  
identical to setpgid (the sources for these assertions are,  
respectively, http://linux.about.com/library/cmd/blcmdl2_setpgrp.htm 
and 'man setpgrp' on OSX).  It appears that having primitiveSetPGrp()  
call setpgid(0,0) would be the most compatible approach.

Thanks again,
Josh



On Mar 18, 2007, at 9:48 AM, David T. Lewis wrote:

> Hi Josh,
>
> I did some more work on this problem, and came up with a good
> way to address it. You will need to build a new OSProcessPlugin
> and load the latest OSProcess, after which you can do:
>
> OSProcess thisOSProcess killCurrentChildrenAtExit
>
> This makes use of atexit() to arrange for any currently active child
> processes to receive a SIGTERM signal when your Squeak VM exits,
> regardless of whether the normal image #shutDown processing occurs.
> By "currently active" I mean the child processes that have already
> been started, and that are running at the time you do the
> #killCurrentChildrenAtExit.
>
> I also added primitives to support Unix setsid(), getpgid(), setpgid
> (),
> getpgrp(), setpgrp() session management functions. You can use these
> if you want to experiment further (but I think  
> #killCurrentChildrenAtExit
> is much easier).
>
> The latest OSProcessPlugin and OSProcess are here:
>  http://www.squeaksource.com/OSProcessPlugin/VMConstruction-Plugins- 
> OSProcessPlugin-dtl.8.mcz
>  http://www.squeaksource.com/OSProcess/OSProcess-dtl.33.mcz
>
> If you try this out, please let me know if it works for you.
>
> Dave
>
> On Thu, Mar 15, 2007 at 11:12:01AM -0700, Joshua Gargus wrote:
>> Hi David,
>>
>> Thanks, that's what I had implemented.  However, the OS X VM has a
>> menu item "Quit do not save" which appears not to go through the
>> regular Squeak shutdown process.  Also, you never know when you'll
>> have to terminate an image with "extreme prejudice" :-)
>>
>> I suppose that another option would be to stash the pids in a file
>> and kill them on startup.
>>
>> Thanks to you and John for the suggestions.  I'm not a unix expert,
>> and I had no idea what support the underlying APIs had for this use
>> case.
>>
>> Cheers,
>> Josh
>>
>>
>> On Mar 15, 2007, at 4:58 AM, David T. Lewis wrote:
>>
>>> On Thu, Mar 15, 2007 at 12:15:01AM -0700, Joshua Gargus wrote:
>>>> Hi,
>>>>
>>>> Is there a way to use OSProcess on OS X (or unix in general) to  
>>>> cause
>>>> forked child processes to die when the parent Squeak process quits?
>>>
>>> You can keep track of the process proxy for the forked child
>>> process, and explicitly terminate it when you exit Squeak, possibly
>>> as part of a class #shutDown: method.
>>>
>>> For example, you can kill all child processes like this:
>>>  OSProcess thisOSProcess allMyChildren do: [:e | e terminate]
>>>
>>> Dave
>>>
>>>
>>


Reply | Threaded
Open this post in threaded view
|

Re: OSProcess: making sure that a child process always dies

David T. Lewis
On Tue, Mar 20, 2007 at 04:12:35PM -0700, Joshua Gargus wrote:

> Hi David,
>
> In order to compile the plugin on OS X (using Ian's 3.9-8 from  
> squeakvm.org) I had to hack UnixOSProcessPlugin.c so that  
> primitiveSetPGrp() calls 'setpgrp(0,0)' instead of 'setpgrp()'.
>
> It appears that OS X and Linux treat these differently.  Under Linux,  
> setpgrp() calls setpgid(0,0) , whereas under OS X, setpgrp is  
> identical to setpgid (the sources for these assertions are,  
> respectively, http://linux.about.com/library/cmd/blcmdl2_setpgrp.htm 
> and 'man setpgrp' on OSX).  It appears that having primitiveSetPGrp()  
> call setpgid(0,0) would be the most compatible approach.

Josh,

Great, thanks a lot for letting me know about this. I'll make the
change as you suggest and update it on SqueakSource.

Much appreciated!

Dave