JDK-8288984 : Simplification in java.lang.Runtime::exit
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 20
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2022-06-22
  • Updated: 2022-07-18
  • Resolved: 2022-07-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 20
20 b06Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Description
In Shutdown.exit there used to be a window between running the shutdown hooks and calling halt where another thread could slip in its own call to exit.  This was to allow finalizers to call exit and halt immediately.  But runFinalizersOnExit was removed (JDK-8198249), so that's no longer an issue.

But that change left a small window ajar for another thread to slip in a call to exit that will immediately call halt. Specifically, in Shutdown.exit there is an initial synchronized block that tests `status != 0 && VM.isShutdown()` and calls halt immediately if so. This creates a very small window of opportunity, where a previous call to exit has completed runHooks (and so made VM.isShutdown true) and calling halt.  A different thread calling exit in that window will override the original status.

I think there is no need for that, and that whole synchronized block should be deleted.  Having it makes the code harder to understand, to no purpose.

Consider a call to exit.

If some other thread has already called exit, it owns the Shutdown.class lock and will retain it through its call to halt.  The new call to exit will just block on the Shutdown.class lock, regardless of whether the earlier call has completed running the shutdown hooks or not.

If instead, some other thread has already called shutdown (which doesn't call halt), then the new call to exit will again block on the Shutdown.class lock.  But this time it will obtain the lock when the call to shutdown completes.  It will then attempt to run the shutdown hooks and discover they've already been run, so do nothing with them.  It will then proceed on to call halt.


Comments
Changeset: ea12615d Author: Ryan Ernst <ryan@iernst.net> Committer: Chris Hegarty <chegar@openjdk.org> Date: 2022-07-12 13:50:36 +0000 URL: https://git.openjdk.org/jdk/commit/ea12615d2f4574467d93cca6b4cc81fc18986307
12-07-2022

[~chegar] That's fine with me.
04-07-2022

@kbarrett - over in the (linked) PR for this issue, there is a conversation relating to expanding the scope of this issue - to clarify a small paragraph of the j.l.Runtime::exit specification. This is desirable, since the implementation and specification changes are directly related. Unless there is an objection, then we should update this JIRA to reflect the expanded scope - "Simplification in Runtime.exit".
03-07-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/9351 Date: 2022-07-01 20:01:48 +0000
01-07-2022

Assigning to myself, as a place holder for now. The task as outlined seems relatively straightforward, but due diligence will require understanding and verify the history and evolution that led to this point, as well as checking the various code paths to ensure that such a simplifying change is indeed correct and appropriate (which I have no reason to think otherwise).
30-06-2022