On Thu, 2012-08-09 at 09:54 +0100, Alan Bateman wrote:
> On 08/08/2012 17:10, Neil Richards wrote:
> > :
> > Hi Alan,
> > Apologies, I confused myself about the Hotspot behaviour.
> > (I was testing with 'nohup', but not checking the contents of
> > 'nohup.out' for the output from my registered shutdown hook - doh!).
> >
> > You're correct, when running with Hotspot with 'nohup', no exception is
> > thrown when trying to register a handler for SIGHUP.
> >
> > When running with J9 with 'nohup', the VM notices that a handler
> > registered for SIGHUP is never going to get triggered, so throws the
> > exception to notify the caller (of Signal.handle( )) about this.
> >
> > Regards,
> > Neil
> This probably comes back to documenting the interface between the VM and 
> the libraries that you and Steve are working on. In this case, 
> JVM_RegisterSignal is expected to return 1 when the action is SIG_IGN 
> where it sounds like J9 is returning -1.
> 
> -Alan.

Hi Alan,
Thanks for your response.

First, I think the discussion on the particular VM implementation
behaviour is a slight diversion from Frank's suggested change, which I
believe is all about making the Java code more robust / agnostic to the
VM implementation behaviour.

>From the perspective of the code in Terminator.setup(), I think the
pertinent question is: 
        Should the code try to register shutdown hook handlers for other
        signals if the attempt to register for one signal fails with an
        exception?
Or, to put it another way:
        Should the registration of the shutdown hook handler for each
        signal be independent of each other?

Frank's suggested change, and my argument, is that these registrations
should be independent - i.e. that Terminator.setup() should register
shutdown hook handlers for all (shutdown) signals that the system (VM)
allows it to.

It is self-evident from the Signal.handle() method that it may throw an
exception on failure to register a handler - that's declared in its
signature, after all - so Terminator.setup() should be coded to robustly
handle that condition.

Discussions on particular VM implementations' behaviours below
Signal.handle() just serves to reinforce the rationale and efficacy of
the suggested change, I feel.

---

Having said that, and separate from the specifics of Frank's changes, I
think it's interesting to consider what is the best behaviour of
Signal.handle() (and JVM_RegisterSignal that underpins it).

Let's consider the form of sun.misc.Signal.handle() (ignoring access
modifiers for simplicity:
        SignalHandler handle(Signal sig, SignalHandler newHandler)
                throws IllegalArgumentException;

So, it can return a SignalHandler object, or throw an
IllegalArgumentException (IAG).

If an exception is thrown, it is clear that the SignalHandler given to
handle() has not been successfully registered.

If, instead, a SignalHandler is returned, the returned value is
generally that for the previously registered signal handler - i.e. the
one that has just been replaced with the new handler.

In J9's case, this is precisely the behaviour it provides: if the new
handler is registered, the old handler is returned; if the new handler
is not registered, an exception is thrown.

However, in Hotspot's case, if the current handler is SIG_IGN, the new
handler is not registered, no exception is thrown, and SIG_IGN is
returned.

So, on the surface, the call seems to have "succeeded", but actually,
the new handler has not been registered.

This behaviour forces a caller (who's interested in understanding if
their new handler is actually getting registered) to understand this
extra complexity in behaviour, and to do extra checking around the call
to handle() in case it returns SIG_IGN to account for it.

That doesn't seem to me like well-designed behaviour for the interface. 
I don't see any advantage gained in having this extra semantic
complexity.

Currently, both VMs decide not to replace SIG_IGN with any other
handler, even if the SIG_IGN has been set up via a previous call to
Signal.handle(). 
Thus setting a signal to be ignored is a one-way street to a dead end
(in a vehicle with no reverse).

But note that this behaviour is a choice of the VM (implementer). It
isn't inherently the case that signal set to SIG_IGN can't be replaced
with another action (at the C level), only that the JVM chooses never to
do so.

Perhaps in the future, Java might wish to allow the overriding of
SIG_IGN signal handlers set up via a previous call to Signal.handle(),
whilst respecting the setting if it has genuinely come from the OS /
environment.

(Also note this isn't only an issue for the HUP signal, either - using
"trap '' SIGNUM" can set up (almost) any signal to be ignored.)

So I'd submit J9's behaviour for JVM_RegisterSignal would be the better
on which to standardize.

---

However, I still consider that VM modification would be logically
orthogonal to Frank's suggested change, and suggest that his change
could continue to be approved for contribution at this point, regardless
of the separate VM-related discussion in this area.

Please get back to me with your thoughts and comments on any of the
above.
(If you agree to the separation of concerns I suggest, perhaps the
discussion of the VM-related behaviour should be split to a separate
thread ?)

Regards,
Neil

-- 
Unless stated above:
IBM email: neil_richards at uk.ibm.com
IBM United Kingdom Limited - Registered in England and Wales with number 741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU

Reply via email to